Re: [PATCH] rumpdisk: Defer hardware initialization to avoid deadlock on stat.

2026-01-27 Thread Samuel Thibault
Applied, thanks!

Milos Nikic, le mar. 27 janv. 2026 12:01:00 -0800, a ecrit:
> Currently, rumpdisk initializes the Rump kernel and probes the PCI bus 
> immediately during main(). When rumpdisk is configured as a passive 
> translator (e.g., for /dev/rumpusbdisk), a simple stat or ls on the node 
> triggers translator startup. This causes a second Rump instance to attempt to 
> probe hardware already owned by the primary disk driver, leading to a 
> system-wide deadlock.
> 
> To reproduce:
> stat /dev/rumpdiskusb
> (rump starts again ... deadlock)
> 
> With this patch:
> stat /dev/rumpdiskusb
> (normal printout of stats, no deadlock)
> ---
>  rumpdisk/main.c | 14 +-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/rumpdisk/main.c b/rumpdisk/main.c
> index 3676b472..0bd753e2 100644
> --- a/rumpdisk/main.c
> +++ b/rumpdisk/main.c
> @@ -40,6 +40,15 @@
>  
>  mach_port_t bootstrap_resume_task = MACH_PORT_NULL;
>  
> +static pthread_once_t rump_hw_initialized = PTHREAD_ONCE_INIT;
> +
> +static void
> +do_rump_hw_init (void)
> +{
> +  mach_print("rumpdisk: Initializing Rump block device layer...\n");
> +  rump_register_block ();
> +}
> +
>  static const struct argp_option options[] = {
>{"host-priv-port", 'h', "PORT", 0, "Host private port PORT"},
>{"device-master-port",'d', "PORT", 0, "Device master port PORT"},
> @@ -102,6 +111,7 @@ static const struct argp *rumpdisk_argp_bootup = 
> &rumpdisk_argp;
>  static int __thread wired = 0;
>  static int rumpdisk_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
>  {
> +  pthread_once (&rump_hw_initialized, do_rump_hw_init);
>/* FIXME: we are not wired while receiving our first message.  */
>if (!wired)
>  {
> @@ -150,7 +160,6 @@ main (int argc, char **argv)
>error(1, err, "Missing parameters for bootstrap");
>  }
>  
> -  rump_register_block ();
>machdev_trivfs_init (argc, argv, bootstrap_resume_task, RUMPNAME, "/dev/" 
> RUMPNAME, &bootstrap);
>  
>/* Make sure we will not swap out, in case we drive the disk used for
> @@ -162,6 +171,9 @@ main (int argc, char **argv)
>if (err != KERN_SUCCESS)
>  error (1, err, "cannot get vm_privilege");
>  
> +  if (bootstrap_resume_task != MACH_PORT_NULL)
> +pthread_once (&rump_hw_initialized, do_rump_hw_init);
> +
>machdev_device_init ();
>err = pthread_create (&t, NULL, rumpdisk_multithread_server, NULL);
>if (err)
> -- 
> 2.52.0
> 
> 

-- 
Samuel
quit   When the quit statement is read, the  bc  processor
   is  terminated, regardless of where the quit state-
   ment is found.  For example, "if  (0  ==  1)  quit"
   will cause bc to terminate.
(Seen in the manpage for "bc". Note the "if" statement's logic)



Re: [PATCH] rumpdisk: Defer hardware initialization to avoid deadlock on stat.

2026-01-27 Thread Milos Nikic
It seems like i mistyped in reproduction steps...
The easiest way to deadlock is just to do this inside the live Hurd

 stat /dev/rumpusbdisk

With this patch, that won't be happening any more

Thanks,
Milos

On Tue, Jan 27, 2026 at 12:01 PM Milos Nikic  wrote:

> Currently, rumpdisk initializes the Rump kernel and probes the PCI bus
> immediately during main(). When rumpdisk is configured as a passive
> translator (e.g., for /dev/rumpusbdisk), a simple stat or ls on the node
> triggers translator startup. This causes a second Rump instance to attempt
> to probe hardware already owned by the primary disk driver, leading to a
> system-wide deadlock.
>
> To reproduce:
> stat /dev/rumpdiskusb
> (rump starts again ... deadlock)
>
> With this patch:
> stat /dev/rumpdiskusb
> (normal printout of stats, no deadlock)
> ---
>  rumpdisk/main.c | 14 +-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/rumpdisk/main.c b/rumpdisk/main.c
> index 3676b472..0bd753e2 100644
> --- a/rumpdisk/main.c
> +++ b/rumpdisk/main.c
> @@ -40,6 +40,15 @@
>
>  mach_port_t bootstrap_resume_task = MACH_PORT_NULL;
>
> +static pthread_once_t rump_hw_initialized = PTHREAD_ONCE_INIT;
> +
> +static void
> +do_rump_hw_init (void)
> +{
> +  mach_print("rumpdisk: Initializing Rump block device layer...\n");
> +  rump_register_block ();
> +}
> +
>  static const struct argp_option options[] = {
>{"host-priv-port",   'h', "PORT", 0, "Host private port PORT"},
>{"device-master-port",'d', "PORT", 0, "Device master port PORT"},
> @@ -102,6 +111,7 @@ static const struct argp *rumpdisk_argp_bootup =
> &rumpdisk_argp;
>  static int __thread wired = 0;
>  static int rumpdisk_demuxer (mach_msg_header_t *inp, mach_msg_header_t
> *outp)
>  {
> +  pthread_once (&rump_hw_initialized, do_rump_hw_init);
>/* FIXME: we are not wired while receiving our first message.  */
>if (!wired)
>  {
> @@ -150,7 +160,6 @@ main (int argc, char **argv)
>error(1, err, "Missing parameters for bootstrap");
>  }
>
> -  rump_register_block ();
>machdev_trivfs_init (argc, argv, bootstrap_resume_task, RUMPNAME,
> "/dev/" RUMPNAME, &bootstrap);
>
>/* Make sure we will not swap out, in case we drive the disk used for
> @@ -162,6 +171,9 @@ main (int argc, char **argv)
>if (err != KERN_SUCCESS)
>  error (1, err, "cannot get vm_privilege");
>
> +  if (bootstrap_resume_task != MACH_PORT_NULL)
> +pthread_once (&rump_hw_initialized, do_rump_hw_init);
> +
>machdev_device_init ();
>err = pthread_create (&t, NULL, rumpdisk_multithread_server, NULL);
>if (err)
> --
> 2.52.0
>
>