[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: active swapping using rumpdisk



Michael Kelly, le mar. 19 août 2025 12:48:55 +0100, a ecrit:
> I specified different constants than the IKOT_ ones for the RPC for 'ktype'
> (see port.h). This avoids the issue of how to export the IKOT_ defines to
> the user interface and in any case makes it clear which IKOT types are
> appropriate.

That should be fine indeed. I'd however say we'd probably want to make
MACH_PORT_KTYPE_USER_DEVICE 28 like in the kernel macro.

> diff -ur gnumach.orig/ipc/mach_port.c gnumach/ipc/mach_port.c
> --- gnumach.orig/ipc/mach_port.c	2025-07-31 20:34:14.844151887 +0100
> +++ gnumach/ipc/mach_port.c	2025-08-19 05:40:55.423218382 +0100
> @@ -1567,6 +1567,44 @@
>  	return KERN_SUCCESS;
>  }
>  
> +kern_return_t
> +mach_port_set_ktype(
> +        host_t host_priv,
> +        ipc_space_t space,
> +        mach_port_name_t name,
> +        mach_port_right_t right,
> +        unsigned ktype)
> +{
> +	ipc_port_t port;
> +	kern_return_t kr;
> +
> +	if (host_priv == HOST_NULL)
> +		return KERN_INVALID_HOST;
> +
> +	if (space == IS_NULL)
> +		return KERN_INVALID_TASK;
> +
> +	if (ktype != MACH_PORT_KTYPE_NONE
> +	    && ktype != MACH_PORT_KTYPE_USER_DEVICE)
> +	  return KERN_INVALID_ARGUMENT;

Please mind the non-coherent indent of return.

> +	kr = ipc_object_translate(space, name, right, (ipc_object_t *)&port);
> +	if (kr != KERN_SUCCESS)
> +		return kr;
> +
> +	if (ip_kotype(port) != IKOT_NONE && ip_kotype(port) != IKOT_USER_DEVICE)

We'd need to unlock the port here, don't we?

> +	  return KERN_INVALID_ARGUMENT;
> +
> +	/* port is locked and active */
> +	ipc_kobject_set(port, IKO_NULL,
> +			ktype == MACH_PORT_KTYPE_NONE
> +			? IKOT_NONE
> +			: IKOT_USER_DEVICE);
> +	ip_unlock(port);
> +
> +	return KERN_SUCCESS;
> +}
> +
>  #if	MACH_KDB
>  
>  void


> diff -ur hurd.orig/rumpdisk/block-rump.c hurd/rumpdisk/block-rump.c
> --- hurd.orig/rumpdisk/block-rump.c	2025-07-31 20:36:06.014917781 +0100
> +++ hurd/rumpdisk/block-rump.c	2025-08-19 08:20:48.477079651 +0100
> @@ -27,6 +27,7 @@
>  
>  #include <mach.h>
>  #include <mach/gnumach.h>
> +#include <mach/port.h>
>  #include <hurd.h>
>  #include <hurd/ports.h>
>  #include <device/device.h>
> @@ -327,6 +328,25 @@
>        rump_sys_close (fd);
>        pthread_rwlock_unlock (&rumpdisk_rwlock);
>        return err;
> +    }
> +
> +  /* Configure the receive port as a USER_DEVICE so that IPC messages
> +     destined for rumpdisk will use page lists rather than page map
> +     entries. This strategy prevents pages that are referenced in the
> +     message body from being swapped out until the message has been
> +     processed.
> +  */
> +  err = mach_port_set_ktype (master_host,
> +			     mach_task_self (),
> +			     bd->port.port_right,
> +			     MACH_PORT_RIGHT_RECEIVE,
> +			     MACH_PORT_KTYPE_USER_DEVICE);
> +  if (err != 0)
> +    {
> +      mach_print ("Failed to set receive port as USER_DEVICE\n");
> +      rump_sys_close (fd);
> +      pthread_rwlock_unlock (&rumpdisk_rwlock);
> +      return err;
>      }
>  
>    bd->taken = 1;

We don't want to make this fatal, because that would immediately break a
box that upgrades its hurd package but not its gnumach package. Better
just print a fat warning that swapping might hang.

Also, better print it on stderr and fflush() it. The other mach_print
are just debugging prints that shouldn't ever happen.

Samuel


Reply to: