Properly implemement pci_intr_disestablish(9), so that interrupt
handlers stop being called when the device has been detached. Should fix PR port-xen/47720 (which turns out to not be related to raidframe). While there fix possible races in event_remove_handler() and pirq_establish().
This commit is contained in:
parent
0969553306
commit
916e2df623
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evtchn.h,v 1.22 2013/01/12 17:39:46 bouyer Exp $ */
|
||||
/* $NetBSD: evtchn.h,v 1.23 2015/03/14 10:49:36 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -67,5 +67,6 @@ struct pintrhand {
|
|||
|
||||
struct pintrhand *pirq_establish(int, int, int (*)(void *), void *, int,
|
||||
const char *);
|
||||
void pirq_disestablish(struct pintrhand *);
|
||||
|
||||
#endif /* _XEN_EVENTS_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: evtchn.c,v 1.70 2013/12/03 20:51:00 bouyer Exp $ */
|
||||
/* $NetBSD: evtchn.c,v 1.71 2015/03/14 10:49:36 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Manuel Bouyer.
|
||||
|
@ -54,7 +54,7 @@
|
|||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.70 2013/12/03 20:51:00 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.71 2015/03/14 10:49:36 bouyer Exp $");
|
||||
|
||||
#include "opt_xen.h"
|
||||
#include "isa.h"
|
||||
|
@ -550,16 +550,16 @@ pirq_establish(int pirq, int evtch, int (*func)(void *), void *arg, int level,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (event_set_handler(evtch, pirq_interrupt, ih, level, evname) != 0) {
|
||||
kmem_free(ih, sizeof(struct pintrhand));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ih->pirq = pirq;
|
||||
ih->evtch = evtch;
|
||||
ih->func = func;
|
||||
ih->arg = arg;
|
||||
|
||||
if (event_set_handler(evtch, pirq_interrupt, ih, level, evname) != 0) {
|
||||
kmem_free(ih, sizeof(struct pintrhand));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev_op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
|
||||
physdev_op.u.irq_status_query.irq = pirq;
|
||||
if (HYPERVISOR_physdev_op(&physdev_op) < 0)
|
||||
|
@ -575,6 +575,17 @@ pirq_establish(int pirq, int evtch, int (*func)(void *), void *arg, int level,
|
|||
return ih;
|
||||
}
|
||||
|
||||
void
|
||||
pirq_disestablish(struct pintrhand *ih)
|
||||
{
|
||||
int error = event_remove_handler(ih->evtch, pirq_interrupt, ih);
|
||||
if (error) {
|
||||
printf("pirq_disestablish(%p): %d\n", ih, error);
|
||||
return;
|
||||
}
|
||||
kmem_free(ih, sizeof(struct pintrhand));
|
||||
}
|
||||
|
||||
int
|
||||
pirq_interrupt(void *arg)
|
||||
{
|
||||
|
@ -772,7 +783,6 @@ event_remove_handler(int evtch, int (*func)(void *), void *arg)
|
|||
}
|
||||
ci = ih->ih_cpu;
|
||||
*ihp = ih->ih_evt_next;
|
||||
mutex_spin_exit(&evtlock[evtch]);
|
||||
|
||||
ipls = ci->ci_isources[ih->ih_level];
|
||||
for (ihp = &ipls->ipl_handlers, ih = ipls->ipl_handlers;
|
||||
|
@ -784,6 +794,7 @@ event_remove_handler(int evtch, int (*func)(void *), void *arg)
|
|||
if (ih == NULL)
|
||||
panic("event_remove_handler");
|
||||
*ihp = ih->ih_ipl_next;
|
||||
mutex_spin_exit(&evtlock[evtch]);
|
||||
kmem_free(ih, sizeof (struct intrhand));
|
||||
if (evts->ev_handlers == NULL) {
|
||||
xen_atomic_clear_bit(&ci->ci_evtmask[0], evtch);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pci_intr_machdep.c,v 1.16 2014/03/29 19:28:30 christos Exp $ */
|
||||
/* $NetBSD: pci_intr_machdep.c,v 1.17 2015/03/14 10:49:36 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Manuel Bouyer.
|
||||
|
@ -26,7 +26,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.16 2014/03/29 19:28:30 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.17 2015/03/14 10:49:36 bouyer Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -221,4 +221,5 @@ pci_intr_establish(pci_chipset_tag_t pcitag, pci_intr_handle_t intrh,
|
|||
void
|
||||
pci_intr_disestablish(pci_chipset_tag_t pcitag, void *cookie)
|
||||
{
|
||||
pirq_disestablish(cookie);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue