[PATCH v7 0/2 hurd] Add irqhelp and clean up ddekit
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
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
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
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
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