diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h --- a/sys/compat/linuxkpi/common/include/linux/interrupt.h +++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2021 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -62,8 +62,6 @@ return (0); } -extern void linux_irq_handler(void *); - static inline struct irq_ent * linux_irq_ent(struct device *dev, unsigned int irq) { @@ -76,6 +74,8 @@ return (NULL); } +extern int linux_irq_setup(struct irq_ent *); + static inline int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *arg) @@ -100,16 +100,14 @@ irqe->arg = arg; irqe->handler = handler; irqe->irq = irq; - error = bus_setup_intr(dev->bsddev, res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, linux_irq_handler, irqe, &irqe->tag); + error = linux_irq_setup(irqe); if (error) { bus_release_resource(dev->bsddev, SYS_RES_IRQ, rid, irqe->res); kfree(irqe); - return (-error); + return (error); } list_add(&irqe->links, &dev->irqents); - - return 0; + return (0); } static inline int @@ -124,8 +122,7 @@ irqe = linux_irq_ent(dev, irq); if (irqe == NULL || irqe->tag != NULL) return -EINVAL; - return -bus_setup_intr(dev->bsddev, irqe->res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, linux_irq_handler, irqe, &irqe->tag); + return (linux_irq_setup(irqe)); } static inline void diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013-2018 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2021 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -2370,18 +2370,23 @@ free(ar, M_KMALLOC); } -void +static void linux_irq_handler(void *ent) { struct irq_ent *irqe; - if (linux_set_current_flags(curthread, M_NOWAIT)) - return; - irqe = ent; irqe->handler(irqe->irq, irqe->arg); } +int +linux_irq_setup(struct irq_ent *irqe) +{ + return (-bus_setup_intr(irqe->dev->bsddev, irqe->res, + INTR_TYPE_NET | INTR_MPSAFE | INTR_LINUXKPI, + NULL, linux_irq_handler, irqe, &irqe->tag)); +} + #if defined(__i386__) || defined(__amd64__) int linux_wbinvd_on_all_cpus(void) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -107,7 +107,6 @@ static void intr_event_update(struct intr_event *ie); static int intr_event_schedule_thread(struct intr_event *ie); -static struct intr_thread *ithread_create(const char *name); static void ithread_destroy(struct intr_thread *ithread); static void ithread_execute_handlers(struct proc *p, struct intr_event *ie); @@ -529,7 +528,7 @@ } static struct intr_thread * -ithread_create(const char *name) +ithread_create(const char *name, enum intr_type flags) { struct intr_thread *ithd; struct thread *td; @@ -548,6 +547,9 @@ thread_unlock(td); td->td_pflags |= TDP_ITHREAD; ithd->it_thread = td; + /* check if we need to allocate a LinuxKPI task structure for this thread */ + if (flags & INTR_LINUXKPI) + (lkpi_alloc_current)(td, M_WAITOK); CTR2(KTR_INTR, "%s: created %s", __func__, name); return (ithd); } @@ -615,7 +617,7 @@ else { ie->ie_flags |= IE_ADDING_THREAD; mtx_unlock(&ie->ie_lock); - it = ithread_create("intr: newborn"); + it = ithread_create("intr: newborn", flags); mtx_lock(&ie->ie_lock); ie->ie_flags &= ~IE_ADDING_THREAD; ie->ie_thread = it; diff --git a/sys/sys/bus.h b/sys/sys/bus.h --- a/sys/sys/bus.h +++ b/sys/sys/bus.h @@ -258,6 +258,7 @@ INTR_TYPE_MISC = 16, INTR_TYPE_CLK = 32, INTR_TYPE_AV = 64, + INTR_LINUXKPI = 128, /* this interrupt is used by the LinuxKPI */ INTR_EXCL = 256, /* exclusive interrupt */ INTR_MPSAFE = 512, /* this interrupt is SMP safe */ INTR_ENTROPY = 1024, /* this interrupt provides entropy */