[PATCH v7 0/2 hurd] Add irqhelp and clean up ddekit

2024-03-02 Thread Damien Zammit
Hi,

I figured out that a semaphore is needed in ddekit to wait until
the thread_init(priv) is called.  This was initially confusing
because I thought a semaphore was needed in the irqhelp library, but
it is not required there.

TESTED: copying a large file from hurd to linux and ifup/ifdown 
a few times with 100% success using a recompiled netdde.static

Damien





[PATCH v7 2/2 hurd] ddekit: Use libirqhelp for interrupt registration

2024-03-02 Thread Damien Zammit
Use the new irqhelp library in ddekit and clean up.

---
 libddekit/Makefile|   2 +-
 libddekit/interrupt.c | 208 ++
 2 files changed, 28 insertions(+), 182 deletions(-)

diff --git a/libddekit/Makefile b/libddekit/Makefile
index 88a0c8909..c74ec1128 100644
--- a/libddekit/Makefile
+++ b/libddekit/Makefile
@@ -39,7 +39,7 @@ LCLHDRS = $(installhdrs)  \
 
 OBJS = $(sort $(SRCS:.c=.o))
 
-HURDLIBS = ports shouldbeinlibc hurd-slab
+HURDLIBS = ports shouldbeinlibc hurd-slab irqhelp
 LDLIBS += -lpthread
 
 MIGCOMSFLAGS = -prefix dde_
diff --git a/libddekit/interrupt.c b/libddekit/interrupt.c
index 35f95a68c..fa6631f83 100644
--- a/libddekit/interrupt.c
+++ b/libddekit/interrupt.c
@@ -4,8 +4,6 @@
  * \author  Christian Helmuth 
  * \date2007-01-22
  *
- * FIXME could intloop_param freed after startup?
- * FIXME use consume flag to indicate IRQ was handled
  */
 
 #include 
@@ -13,153 +11,25 @@
 #include 
 #include 
 
-#include 
-#include 
+#include "libirqhelp/irqhelp.h"
 
-#include "ddekit/interrupt.h"
 #include "ddekit/semaphore.h"
+#include "ddekit/thread.h"
+#include "ddekit/interrupt.h"
 #include "ddekit/printf.h"
-#include "ddekit/memory.h"
-#include "ddekit/condvar.h"
-
-#define DEBUG_INTERRUPTS  0
 
 #define MAX_INTERRUPTS   32
 
-#define BLOCK_IRQ 0
-
-/*
- * Internal type for interrupt loop parameters
- */
-struct intloop_params
-{
-   unsigned  irq;   /* irq number */
-   int   shared;/* irq sharing supported? */
-   void(*thread_init)(void *);  /* thread initialization */
-   void(*handler)(void *);  /* IRQ handler function */
-   void *priv;  /* private token */ 
-   mach_port_t   irqport;   /* delivery port for notifications */
-   ddekit_sem_t *started;
-
-   int   start_err;
-};
-
 static struct
 {
int  handle_irq; /* nested irq disable count */
ddekit_lock_tirqlock;
-   struct ddekit_condvar   *cond;
-   ddekit_thread_t  *irq_thread; /* thread ID for detaching from IRQ later 
on */
-   boolean_tthread_exit;
thread_t mach_thread;
+   ddekit_thread_t  *irq_thread;
+   ddekit_sem_t *started;
+   void *irqhelp;   /* irqhelp instance for detaching from IRQ 
*/
 } ddekit_irq_ctrl[MAX_INTERRUPTS];
 
-static mach_port_t master_host;
-static mach_port_t master_device;
-static device_t irq_dev;
-
-/**
- * Interrupt service loop
- *
- */
-static void intloop(void *arg)
-{
-   kern_return_t ret;
-   struct intloop_params *params = arg;
-   mach_port_t delivery_port;
-   mach_port_t pset, psetcntl;
-   int my_index;
-
-   ret = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
- &delivery_port);
-   if (ret)
- error (2, ret, "mach_port_allocate");
-
-   my_index = params->irq;
-   params->irqport = delivery_port;
-   ddekit_irq_ctrl[my_index].mach_thread = mach_thread_self ();
-   ret = thread_get_assignment (mach_thread_self (), &pset);
-   if (ret)
-   error (0, ret, "thread_get_assignment");
-   ret = host_processor_set_priv (master_host, pset, &psetcntl);
-   if (ret)
-   error (0, ret, "host_processor_set_priv");
-   thread_max_priority (mach_thread_self (), psetcntl, 0);
-   ret = thread_priority (mach_thread_self (), DDEKIT_IRQ_PRIO, 0);
-   if (ret)
-   error (0, ret, "thread_priority");
-
-   // TODO the flags for shared irq should be indicated by params->shared.
-   // Flags needs to be 0 for new irq interface for now.
-   // Otherwise, the interrupt handler cannot be installed in the kernel.
-   ret = device_intr_register (irq_dev, my_index,
- 0, delivery_port,
- MACH_MSG_TYPE_MAKE_SEND);
-   ddekit_printf ("device_intr_register returns %d\n", ret);
-   if (ret) {
-   /* inform thread creator of error */
-   /* XXX does omega0 error code have any meaning to DDEKit users? 
*/
-   params->start_err = ret;
-   ddekit_sem_up(params->started);
-   ddekit_printf ("cannot install irq %d\n", my_index);
-   return;
-   }
-
-#if 0
-   /* 
-* Setup an exit fn. This will make sure that we clean up everything,
-* before shutting down an IRQ thread.
-*/
-   if (l4thread_on_exit(&exit_fn, (void *)my_index) < 0)
-   ddekit_panic("Could not set exit handler for IRQ fn.");
-#endif
-
-   /* after successful initialization call thread_init() before doing 
anything
-* else here */
-   if (params->thread_init) params->thread_init(params->priv);
-
-   /* save handle + inform thread creator of success */
-   params->start_err = 0;
-   ddekit_sem_up(params->started);
-
-   int irq_

[PATCH v7 1/2 hurd] libirqhelp: Add library

2024-03-02 Thread Damien Zammit
Add a helper library for attaching interrupt handlers in userspace.

---
 Makefile |   1 +
 libirqhelp/Makefile  |  28 
 libirqhelp/irqhelp.c | 362 +++
 libirqhelp/irqhelp.h |  49 ++
 4 files changed, 440 insertions(+)
 create mode 100644 libirqhelp/Makefile
 create mode 100644 libirqhelp/irqhelp.c
 create mode 100644 libirqhelp/irqhelp.h

diff --git a/Makefile b/Makefile
index 874349c06..4d8482219 100644
--- a/Makefile
+++ b/Makefile
@@ -32,6 +32,7 @@ lib-subdirs = libshouldbeinlibc libihash libiohelp libports \
  libhurd-slab \
  libbpf \
  libmachdev \
+ libirqhelp \
 
 # Hurd programs
 prog-subdirs = auth proc exec term \
diff --git a/libirqhelp/Makefile b/libirqhelp/Makefile
new file mode 100644
index 0..c32632abe
--- /dev/null
+++ b/libirqhelp/Makefile
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+dir := libirqhelp
+makemode := library
+
+SRCS = irqhelp.c acpiUser.c
+
+OBJS = $(SRCS:.c=.o)
+HURDLIBS =
+LDLIBS += -lpthread
+libname = libirqhelp
+installhdrs = irqhelp.h
+
+include ../Makeconf
diff --git a/libirqhelp/irqhelp.c b/libirqhelp/irqhelp.c
new file mode 100644
index 0..32e59c92c
--- /dev/null
+++ b/libirqhelp/irqhelp.c
@@ -0,0 +1,362 @@
+/* Library providing helper functions for userspace irq handling.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "irqhelp.h"
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "acpi_U.h"
+#include 
+#include 
+
+#define IRQ_THREAD_PRIORITY2
+#define log_error(fmt...)  fprintf(stderr, ## fmt)
+
+struct irq {
+  void (*handler)(void *);
+  void *context;
+  int gsi;
+  mach_port_t port;
+  bool enabled;
+  bool shutdown;
+  pthread_mutex_t irqlock;
+  pthread_cond_t irqcond;
+};
+
+static mach_port_t irqdev;
+static mach_port_t acpidev;
+
+static error_t
+get_acpi(void)
+{
+  error_t err = 0;
+  mach_port_t tryacpi, device_master;
+
+  acpidev = MACH_PORT_NULL;
+  err = get_privileged_ports (0, &device_master);
+  if (!err)
+{
+  err = device_open (device_master, D_READ, "acpi", &tryacpi);
+  mach_port_deallocate (mach_task_self (), device_master);
+  if (!err)
+{
+ acpidev = tryacpi;
+  return 0;
+}
+}
+
+  tryacpi = file_name_lookup (_SERVERS_ACPI, O_RDONLY, 0);
+  if (tryacpi == MACH_PORT_NULL)
+return ENODEV;
+
+  acpidev = tryacpi;
+  return 0;
+}
+
+static error_t
+get_irq(void)
+{
+  error_t err = 0;
+  mach_port_t tryirq, device_master;
+
+  irqdev = MACH_PORT_NULL;
+
+  err = get_privileged_ports (0, &device_master);
+  if (err)
+return err;
+
+  err = device_open (device_master, D_READ|D_WRITE, "irq", &tryirq);
+  mach_port_deallocate (mach_task_self (), device_master);
+  if (err)
+return err;
+
+  irqdev = tryirq;
+  return err;
+}
+
+static void
+toggle_irq(struct irq *irq, bool on)
+{
+  pthread_mutex_lock (&irq->irqlock);
+  irq->enabled = on;
+  pthread_mutex_unlock (&irq->irqlock);
+
+  if (on)
+pthread_cond_signal (&irq->irqcond);
+}
+
+error_t
+irqhelp_init(void)
+{
+  static bool inited = false;
+  error_t err;
+
+  if (inited)
+{
+  log_error("already inited\n");
+  return 0;
+}
+
+  err = get_irq();
+  if (err)
+{
+  log_error("cannot grab irq device\n");
+  return err;
+}
+
+  err = get_acpi();
+  if (err)
+{
+  log_error("cannot grab acpi device\n");
+  return err;
+}
+
+  inited = true;
+  r

[PATCH 0/1 hurd] ext2fs - new translator entries in xattrs

2024-03-02 Thread Damien Zammit
Hi,

I have prepared this patch for inclusion into hurd, however
we may need to think of the best migration strategy:

Do we allow a soft migration where translator entries are kept as is,
but new ones are migrated only upon creation. Or do we write a 
script that will migrate all translator entries so users don't end up
with a mish-mash of old and new ones on their systems?   

Damien





[PATCH 1/1 hurd] ext2fs: New default: use xattrs to store translator records

2024-03-02 Thread Damien Zammit
Replaces experimental option --x-xattr-translator-records
with --no-xattr-translator-records to allow rolling back to
previous behaviour.

NB:
  - Legacy records still work with either setting.
  - Adding a new record removes a legacy one.
---
 ext2fs/ext2fs.c | 18 +-
 ext2fs/inode.c  | 25 +++--
 2 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c
index 3c76d8c8..3836bdf6 100644
--- a/ext2fs/ext2fs.c
+++ b/ext2fs/ext2fs.c
@@ -89,15 +89,14 @@ struct ext2_group_desc *group_desc_image;
 
 struct pokel global_pokel;
 
-int use_xattr_translator_records;
 
 #ifdef EXT2FS_DEBUG
 int ext2_debug_flag;
 #endif
 
 /* Use extended attribute-based translator records.  */
-int use_xattr_translator_records;
-#define X_XATTR_TRANSLATOR_RECORDS -1
+int use_xattr_translator_records = 1;
+#define NO_XATTR_TRANSLATOR_RECORDS-1
 
 /* Ext2fs-specific options.  */
 static const struct argp_option
@@ -108,8 +107,8 @@ options[] =
" (not compiled in)"
 #endif
   },
-  {"x-xattr-translator-records", X_XATTR_TRANSLATOR_RECORDS, 0, 0,
-   "Store translator records in extended attributes (experimental)"},
+  {"no-xattr-translator-records", NO_XATTR_TRANSLATOR_RECORDS, 0, 0,
+   "Do not store translator records in extended attributes (legacy)"},
 #ifdef ALTERNATE_SBLOCK
   /* XXX This is not implemented.  */
   {"sblock", 'S', "BLOCKNO", 0,
@@ -138,8 +137,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
 case 'D':
   values->debug_flag = 1;
   break;
-case X_XATTR_TRANSLATOR_RECORDS:
-  values->use_xattr_translator_records = 1;
+case NO_XATTR_TRANSLATOR_RECORDS:
+  values->use_xattr_translator_records = 0;
   break;
 #ifdef ALTERNATE_SBLOCK
 case 'S':
@@ -159,6 +158,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
return ENOMEM;
   state->hook = values;
   memset (values, 0, sizeof *values);
+  values->use_xattr_translator_records = use_xattr_translator_records;
 #ifdef ALTERNATE_SBLOCK
   values->sb_block = SBLOCK_BLOCK;
 #endif
@@ -194,8 +194,8 @@ diskfs_append_args (char **argz, size_t *argz_len)
   /* Get the standard things.  */
   err = diskfs_append_std_options (argz, argz_len);
 
-  if (!err && use_xattr_translator_records)
-err = argz_add (argz, argz_len, "--x-xattr-translator-records");
+  if (!err && !use_xattr_translator_records)
+err = argz_add (argz, argz_len, "--no-xattr-translator-records");
 
 #ifdef EXT2FS_DEBUG
   if (!err && ext2_debug_flag)
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index 5b99069e..ead82678 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -764,19 +764,24 @@ diskfs_get_translator (struct node *np, char **namep, 
mach_msg_type_number_t *na
   return err;
 }
 
-  err = ext2_get_xattr (np, "gnu.translator", NULL, &datalen);
-  if (err)
-return err;
+  /* If xattr is supported by this filesystem, check for new translator record
+   * regardless of flag to use it or not */
+  if (EXT2_HAS_COMPAT_FEATURE (sblock, EXT2_FEATURE_COMPAT_EXT_ATTR))
+{
+  err = ext2_get_xattr (np, "gnu.translator", NULL, &datalen);
+  if (err)
+return err;
 
-  *namep = malloc (datalen);
-  if (!*namep)
-err = ENOMEM;
-  else
-err = ext2_get_xattr (np, "gnu.translator", *namep, &datalen);
+  *namep = malloc (datalen);
+  if (!*namep)
+err = ENOMEM;
+  else
+err = ext2_get_xattr (np, "gnu.translator", *namep, &datalen);
 
-  diskfs_end_catch_exception ();
+  diskfs_end_catch_exception ();
 
-  *namelen = datalen;
+  *namelen = datalen;
+}
   return err;
 }
 
-- 
2.43.0