bug-hurd
[Top][All Lists]
Advanced

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

Re: [PATCH 3/5] acpi: Convert translator to an emulated mach device


From: Samuel Thibault
Subject: Re: [PATCH 3/5] acpi: Convert translator to an emulated mach device
Date: Tue, 6 Sep 2022 01:05:15 +0200
User-agent: NeoMutt/20170609 (1.8.3)

Please also mention in the commit log that it's meant to make it usable
as bootstrap translator.

Damien Zammit, le dim. 04 sept. 2022 03:47:19 +0000, a ecrit:
> diff --git a/acpi/acpifs.c b/acpi/acpifs.c
> index 2b5fbc00..75cc2e28 100644
> --- a/acpi/acpifs.c
> +++ b/acpi/acpifs.c
> @@ -106,18 +109,27 @@ init_file_system (file_t underlying_node, struct acpifs 
> *fs)
>    fshelp_touch (&np->nn_stat, TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME,
>                 acpifs_maptime);
> 
> +  netfs_root_node = np;
> +  return 0;
> +}
> +
> +error_t
> +init_file_system (struct acpifs *fs)
> +{
> +  error_t err;
> +  struct node *np = netfs_root_node;
> +
>    fs->entries = calloc (1, sizeof (struct acpifs_dirent));
>    if (!fs->entries)
> -    {
> -      free (fs->entries);
> -      return ENOMEM;
> -    }
> +    return ENOMEM;
> 
>    /* Create the root entry */
>    err = create_dir_entry ("", 0, 0, np->nn_stat, np, fs->entries);
> +  if (err)
> +    return err;

Also free fs->entries?

> 
>    fs->num_entries = 1;
> -  fs->root = netfs_root_node = np;
> +  fs->root = np;
>    fs->root->nn->ln = fs->entries;
>    pthread_mutex_init (&fs->node_cache_lock, 0);
> 
> diff --git a/acpi/main.c b/acpi/main.c
> index 9cb6f3a1..c5de2742 100644
> --- a/acpi/main.c
> +++ b/acpi/main.c
> @@ -25,14 +25,19 @@
>  #include <version.h>
>  #include <argp.h>
>  #include <hurd/netfs.h>
> +#include <hurd/fsys.h>
> 
>  #include "acpi_S.h"
> +#include "startup_notify_S.h"
>  #include "libnetfs/io_S.h"
>  #include "libnetfs/fs_S.h"
>  #include "libports/notify_S.h"
>  #include "libnetfs/fsys_S.h"
>  #include "libports/interrupt_S.h"
>  #include "libnetfs/ifsock_S.h"
> +#include "libmachdev/machdev.h"
> +#include <device/device.h>
> +#include <pthread.h>
>  #include <acpi/acpi_init.h>
>  #include <acpifs.h>
> 
> @@ -45,24 +50,110 @@ volatile struct mapped_time_value *acpifs_maptime;
> 
>  struct acpifs *fs;
> 
> -int
> -netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
> +static mach_port_t acpi_control_port;
> +
> +
> +static io_return_t
> +acpi_device_open (mach_port_t reply_port, mach_msg_type_name_t 
> reply_port_type,
> +               dev_mode_t mode, const char *name, device_t * devp,
> +               mach_msg_type_name_t * devicePoly)
>  {
> -  mig_routine_t routine;
> +  io_return_t err = D_SUCCESS;
> +  mach_port_t dev_master, root;
> +  string_t retry_name;
> +  retry_type retry;
> +  uid_t idlist[] = {0, 0, 0};
> 
> -  if ((routine = netfs_io_server_routine (inp)) ||
> -      (routine = netfs_fs_server_routine (inp)) ||
> -      (routine = ports_notify_server_routine (inp)) ||
> -      (routine = netfs_fsys_server_routine (inp)) ||
> -      (routine = ports_interrupt_server_routine (inp)) ||
> -      (routine = netfs_ifsock_server_routine (inp)) ||
> -      (routine = S_acpi_server_routine (inp)))
> +  if (strncmp(name, "acpi", 3))
> +    err = D_NO_SUCH_DEVICE;
> +
> +  /* Fall back to opening kernel device master */
> +  if (err)
>      {
> -      (*routine) (inp, outp);
> -      return TRUE;
> +      err = get_privileged_ports(NULL, &dev_master);
> +      if (err)
> +        return err;
> +      if (dev_master == MACH_PORT_NULL)
> +        return D_NO_SUCH_DEVICE;
> +      err = device_open (dev_master, mode, name, devp);
> +      if (err)
> +        return err;
> +      *devicePoly = MACH_MSG_TYPE_MOVE_SEND;
> +      return D_SUCCESS;
>      }
> -  else
> -    return FALSE;
> +
> +  err = fsys_getroot(acpi_control_port, MACH_PORT_NULL, 
> MACH_MSG_TYPE_COPY_SEND,
> +                     idlist, 3, idlist, 3, 0,
> +                     &retry, retry_name, &root);
> +  if (err)
> +    return err;
> +
> +  *devp = root;
> +  *devicePoly = MACH_MSG_TYPE_COPY_SEND;
> +  return D_SUCCESS;
> +}
> +
> +static struct machdev_device_emulation_ops acpi_emulation_ops = {
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  acpi_device_open,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +};
> +
> +static void *
> +netfs_server_func (void *arg)
> +{
> +  error_t err;
> +
> +  do
> +    {
> +      ports_manage_port_operations_multithread (netfs_port_bucket,
> +                                             netfs_demuxer,
> +                                             1000 * 60 * 2, /* two minutes 
> thread */
> +                                             1000 * 60 * 10,/* ten minutes 
> server */
> +                                             0);
> +      err = netfs_shutdown (0);
> +    }
> +  while (err);
> +  return NULL;
> +}
> +
> +static mach_port_t
> +acpifs_startup(mach_port_t bootstrap, int flags)
> +{
> +  error_t err;
> +  mach_port_t realnode;
> +  struct port_info *newpi;
> +
> +  err = ports_create_port (netfs_control_class, netfs_port_bucket,
> +                          sizeof (struct port_info), &newpi);
> +  if (err)
> +    error (11, err, "Translator startup failure: acpifs_startup");
> +
> +  acpi_control_port = ports_get_send_right (newpi);
> +
> +  if (bootstrap != MACH_PORT_NULL)
> +    {
> +      err = fsys_startup (bootstrap, flags, acpi_control_port, 
> MACH_MSG_TYPE_COPY_SEND,
> +                          &realnode);
> +      assert_perror_backtrace (err);
> +    }
> +
> +  return realnode;
>  }
> 
>  int
> @@ -70,18 +161,36 @@ main (int argc, char **argv)
>  {
>    error_t err;
>    mach_port_t bootstrap;
> +  mach_port_t next_task;
> +  pthread_t t, nt;
> +  file_t underlying_node = MACH_PORT_NULL;
> 
>    /* Parse options */
>    alloc_file_system (&fs);
>    argp_parse (netfs_runtime_argp, argc, argv, 0, 0, 0);
> +  next_task = fs->next_task;
> 
> -  task_get_bootstrap_port (mach_task_self (), &bootstrap);
> -  if (bootstrap == MACH_PORT_NULL)
> -    error (1, 0, "must be started as a translator");
> +  if (next_task != MACH_PORT_NULL)
> +    {
> +      /* We are a bootstrap process */
> 
> -  /* Initialize ACPI */
> -  acpi_init();
> +      machdev_register (&acpi_emulation_ops);
> +      /* TODO: make libmachdev allow us to also run netfs on the translated 
> path,
> +       * so that we don't need a second acpi to serve /servers/acpi  */
> +      machdev_trivfs_init (argc, argv, next_task, "acpi", NULL /* _SERVERS 
> "acpi" */, &bootstrap);
> 
> +      machdev_device_init ();
> +      err = pthread_create (&t, NULL, machdev_server, NULL);
> +      if (err)
> +        error (1, err, "creating machdev thread");
> +      pthread_detach (t);
> +    }
> +  else
> +    {
> +      task_get_bootstrap_port (mach_task_self (), &bootstrap);
> +      if (bootstrap == MACH_PORT_NULL)
> +        error (1, 0, "must be started as a translator");
> +    }
>    /* Initialize netfs and start the translator. */
>    netfs_init ();
> 
> @@ -91,8 +200,34 @@ main (int argc, char **argv)
>    if (err)
>      error (1, err, "mapping time");
> 
> -  /* Create the ACPI filesystem */
> -  err = init_file_system (netfs_startup (bootstrap, O_READ), fs);
> +  /* Enable ACPI mode of machine */
> +  acpi_init ();
> +
> +  if (next_task != MACH_PORT_NULL)
> +    {
> +      void *run_server(void *arg) {
> +     machdev_trivfs_server(bootstrap);
> +     return NULL;
> +      }
> +
> +      pthread_t t;
> +      pthread_create(&t, NULL, run_server, NULL);
> +      pthread_detach(t);
> +      /* Timer started, quickly do all these next, before we call rump_init 
> */

machdev_trivfs_server can probably be split into two functions, so that
one can run the initialization part sequentially in the main thread,
then initialize the rest, and then only start the libmachdev demuxer in
another thread.

> +    }
> +
> +  if (next_task == MACH_PORT_NULL)
> +    underlying_node = netfs_startup (bootstrap, O_READ);
> +
> +  /* Create the root node first */
> +  err = init_root_node (underlying_node);
> +  if (err)
> +    error (1, err, "creating the root node");
> +
> +  if (next_task != MACH_PORT_NULL)
> +    acpifs_startup (bootstrap, O_READ);
> +
> +  err = init_file_system (fs);
>    if (err)
>      error (1, err, "creating the ACPI filesystem");
> 
> @@ -106,7 +241,34 @@ main (int argc, char **argv)
>    if (err)
>      error (1, err, "setting permissions");
> 
> -  netfs_server_loop (); /* Never returns.  */
> +  err = pthread_create (&nt, NULL, netfs_server_func, NULL);
> +  if (err)
> +    error (1, err, "creating netfs loop thread");
> +  pthread_detach (nt);
> 
> +  /* Let the other threads do their job */
> +  pthread_exit(NULL);
> +  /* Never reached */

Why not leaving it calling netfs_server_loop?
I don't remember why we did that in pci-arbiter/main.c.
(which means we should have left a comment telling why)

Samuel



reply via email to

[Prev in Thread] Current Thread [Next in Thread]