Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

um: ubd: Switch to the pthread-based helper

The ubd io thread and UML kernel thread share the same errno, which
can lead to conflicts when both call syscalls concurrently. Switch to
the pthread-based helper to address this issue.

Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com>
Link: https://patch.msgid.link/20250319135523.97050-3-tiwei.btw@antgroup.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Tiwei Bie and committed by
Johannes Berg
d7f89a9d 4f087eaf

+22 -23
+4 -2
arch/um/drivers/ubd.h
··· 7 7 #ifndef __UM_UBD_USER_H 8 8 #define __UM_UBD_USER_H 9 9 10 - extern int start_io_thread(unsigned long sp, int *fds_out); 11 - extern int io_thread(void *arg); 10 + #include <os.h> 11 + 12 + int start_io_thread(struct os_helper_thread **td_out, int *fd_out); 13 + void *io_thread(void *arg); 12 14 extern int kernel_fd; 13 15 14 16 extern int ubd_read_poll(int timeout);
+11 -14
arch/um/drivers/ubd_kern.c
··· 474 474 } 475 475 476 476 /* Only changed by ubd_init, which is an initcall. */ 477 - static int io_pid = -1; 477 + static struct os_helper_thread *io_td; 478 478 479 479 static void kill_io_thread(void) 480 480 { 481 - if(io_pid != -1) 482 - os_kill_process(io_pid, 1); 481 + if (io_td) 482 + os_kill_helper_thread(io_td); 483 483 } 484 484 485 485 __uml_exitcall(kill_io_thread); ··· 1104 1104 1105 1105 late_initcall(ubd_init); 1106 1106 1107 - static int __init ubd_driver_init(void){ 1108 - unsigned long stack; 1107 + static int __init ubd_driver_init(void) 1108 + { 1109 1109 int err; 1110 1110 1111 1111 /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/ ··· 1114 1114 /* Letting ubd=sync be like using ubd#s= instead of ubd#= is 1115 1115 * enough. So use anyway the io thread. */ 1116 1116 } 1117 - stack = alloc_stack(0, 0); 1118 - io_pid = start_io_thread(stack + PAGE_SIZE, &thread_fd); 1119 - if(io_pid < 0){ 1117 + err = start_io_thread(&io_td, &thread_fd); 1118 + if (err < 0) { 1120 1119 printk(KERN_ERR 1121 1120 "ubd : Failed to start I/O thread (errno = %d) - " 1122 - "falling back to synchronous I/O\n", -io_pid); 1123 - io_pid = -1; 1121 + "falling back to synchronous I/O\n", -err); 1124 1122 return 0; 1125 1123 } 1126 1124 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, ··· 1494 1496 /* Only changed by the io thread. XXX: currently unused. */ 1495 1497 static int io_count; 1496 1498 1497 - int io_thread(void *arg) 1499 + void *io_thread(void *arg) 1498 1500 { 1499 1501 int n, count, written, res; 1500 1502 1501 - os_set_pdeathsig(); 1502 - os_fix_helper_signals(); 1503 + os_fix_helper_thread_signals(); 1503 1504 1504 1505 while(1){ 1505 1506 n = bulk_req_safe_read( ··· 1540 1543 } while (written < n); 1541 1544 } 1542 1545 1543 - return 0; 1546 + return NULL; 1544 1547 }
+7 -7
arch/um/drivers/ubd_user.c
··· 25 25 26 26 static struct pollfd kernel_pollfd; 27 27 28 - int start_io_thread(unsigned long sp, int *fd_out) 28 + int start_io_thread(struct os_helper_thread **td_out, int *fd_out) 29 29 { 30 - int pid, fds[2], err; 30 + int fds[2], err; 31 31 32 32 err = os_pipe(fds, 1, 1); 33 33 if(err < 0){ ··· 47 47 goto out_close; 48 48 } 49 49 50 - pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM, NULL); 51 - if(pid < 0){ 52 - err = -errno; 53 - printk("start_io_thread - clone failed : errno = %d\n", errno); 50 + err = os_run_helper_thread(td_out, io_thread, NULL); 51 + if (err < 0) { 52 + printk("%s - failed to run helper thread, err = %d\n", 53 + __func__, -err); 54 54 goto out_close; 55 55 } 56 56 57 - return(pid); 57 + return 0; 58 58 59 59 out_close: 60 60 os_close_file(fds[0]);