Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133079906
D30936.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D30936.id.diff
View Options
diff --git a/sys/dev/xen/bus/intr-internal.h b/sys/dev/xen/bus/intr-internal.h
--- a/sys/dev/xen/bus/intr-internal.h
+++ b/sys/dev/xen/bus/intr-internal.h
@@ -77,6 +77,9 @@
* <machine/xen/arch-intr.h>. The architecture may implement these as inline.
*/
void xen_arch_intr_init(void);
+struct xenisrc *xen_arch_intr_alloc(void);
+void xen_arch_intr_release(struct xenisrc *isrc);
+u_int xen_arch_intr_next_cpu(struct xenisrc *isrc);
u_long xen_arch_intr_execute_handlers(struct xenisrc *isrc,
struct trapframe *frame);
int xen_arch_intr_add_handler(const char *name,
diff --git a/sys/x86/include/xen/arch-intr.h b/sys/x86/include/xen/arch-intr.h
--- a/sys/x86/include/xen/arch-intr.h
+++ b/sys/x86/include/xen/arch-intr.h
@@ -30,20 +30,29 @@
#define _MACHINE__XEN_ARCH_INTR_H_
#include <x86/intr_machdep.h>
+#include <x86/apicvar.h>
typedef struct {
struct intsrc intsrc; /* @TOP -> *xen_arch_isrc */
u_int vector; /* Global isrc vector number */
} xen_arch_isrc_t;
-extern struct pic xen_intr_pic;
-
#include <dev/xen/bus/intr-internal.h>
/******************************* ARCH wrappers *******************************/
extern void xen_arch_intr_init(void);
+extern struct xenisrc *xen_arch_intr_alloc(void);
+extern void xen_arch_intr_release(struct xenisrc *isrc);
+
+static inline u_int
+xen_arch_intr_next_cpu(struct xenisrc *isrc)
+{
+
+ return (apic_cpuid(intr_next_cpu(0)));
+}
+
static inline u_long
xen_arch_intr_execute_handlers(struct xenisrc *isrc, struct trapframe *frame)
{
diff --git a/sys/x86/xen/xen_arch_intr.c b/sys/x86/xen/xen_arch_intr.c
--- a/sys/x86/xen/xen_arch_intr.c
+++ b/sys/x86/xen/xen_arch_intr.c
@@ -111,6 +111,41 @@
/******************************** EVTCHN PIC *********************************/
+static MALLOC_DEFINE(M_XENINTR, "xen_intr", "Xen Interrupt Services");
+
+/*
+ * Lock for x86-related structures. Notably modifying
+ * xen_intr_auto_vector_count, and allocating interrupts require this lock be
+ * held.
+ */
+static struct mtx xen_intr_x86_lock;
+
+static u_int first_evtchn_irq;
+
+static u_int xen_intr_auto_vector_count;
+
+/*
+ * list of released isrcs
+ * This is meant to overlay struct xenisrc, with only the xen_arch_isrc_t
+ * portion being preserved, everything else can be wiped.
+ */
+struct avail_list {
+ xen_arch_isrc_t preserve;
+ SLIST_ENTRY(avail_list) free;
+};
+static SLIST_HEAD(free, avail_list) avail_list =
+ SLIST_HEAD_INITIALIZER(avail_list);
+
+void
+xen_intr_alloc_irqs(void)
+{
+
+ if (num_io_irqs > UINT_MAX - NR_EVENT_CHANNELS)
+ panic("IRQ allocation overflow (num_msi_irqs too high?)");
+ first_evtchn_irq = num_io_irqs;
+ num_io_irqs += NR_EVENT_CHANNELS;
+}
+
static void
xen_intr_pic_enable_source(struct intsrc *isrc)
{
@@ -244,7 +279,7 @@
/**
* PIC interface for all event channel port types except physical IRQs.
*/
-struct pic xen_intr_pic = {
+static struct pic xen_intr_pic = {
.pic_enable_source = xen_intr_pic_enable_source,
.pic_disable_source = xen_intr_pic_disable_source,
.pic_eoi_source = xen_intr_pic_eoi_source,
@@ -265,8 +300,86 @@
{
int error;
+ mtx_init(&xen_intr_x86_lock, "xen-x86-table-lock", NULL, MTX_DEF);
+
error = intr_register_pic(&xen_intr_pic);
if (error != 0)
panic("%s(): failed registering Xen/x86 PIC, error=%d\n",
__func__, error);
}
+
+/**
+ * Allocate a Xen interrupt source object.
+ *
+ * \param type The type of interrupt source to create.
+ *
+ * \return A pointer to a newly allocated Xen interrupt source
+ * object or NULL.
+ */
+struct xenisrc *
+xen_arch_intr_alloc(void)
+{
+ static int warned;
+ struct xenisrc *isrc;
+ unsigned int vector;
+ int error;
+
+ mtx_lock(&xen_intr_x86_lock);
+ isrc = (struct xenisrc *)SLIST_FIRST(&avail_list);
+ if (isrc != NULL) {
+ SLIST_REMOVE_HEAD(&avail_list, free);
+ mtx_unlock(&xen_intr_x86_lock);
+
+ KASSERT(isrc->xi_arch.intsrc.is_pic == &xen_intr_pic,
+ ("interrupt not owned by Xen code?"));
+
+ KASSERT(isrc->xi_arch.intsrc.is_handlers == 0,
+ ("Free evtchn still has handlers"));
+
+ return (isrc);
+ }
+
+ if (xen_intr_auto_vector_count >= NR_EVENT_CHANNELS) {
+ if (!warned) {
+ warned = 1;
+ printf("%s: Xen interrupts exhausted.\n", __func__);
+ }
+ mtx_unlock(&xen_intr_x86_lock);
+ return (NULL);
+ }
+
+ vector = first_evtchn_irq + xen_intr_auto_vector_count;
+ xen_intr_auto_vector_count++;
+
+ KASSERT((intr_lookup_source(vector) == NULL),
+ ("Trying to use an already allocated vector"));
+
+ mtx_unlock(&xen_intr_x86_lock);
+ isrc = malloc(sizeof(*isrc), M_XENINTR, M_WAITOK | M_ZERO);
+ isrc->xi_arch.intsrc.is_pic = &xen_intr_pic;
+ isrc->xi_arch.vector = vector;
+ error = intr_register_source(&isrc->xi_arch.intsrc);
+ if (error != 0)
+ panic("%s(): failed registering interrupt %u, error=%d\n",
+ __func__, vector, error);
+
+ return (isrc);
+}
+
+void
+xen_arch_intr_release(struct xenisrc *isrc)
+{
+
+ KASSERT(isrc->xi_arch.intsrc.is_handlers == 0,
+ ("Release called, but xenisrc still in use"));
+
+ _Static_assert(sizeof(struct xenisrc) >= sizeof(struct avail_list),
+ "unused structure MUST be no larger than in-use structure");
+ _Static_assert(offsetof(struct xenisrc, xi_arch) ==
+ offsetof(struct avail_list, preserve),
+ "unused structure does not properly overlay in-use structure");
+
+ mtx_lock(&xen_intr_x86_lock);
+ SLIST_INSERT_HEAD(&avail_list, (struct avail_list *)isrc, free);
+ mtx_unlock(&xen_intr_x86_lock);
+}
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -38,7 +38,6 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
-#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
@@ -68,17 +67,6 @@
#include <ddb/ddb.h>
#endif
-static MALLOC_DEFINE(M_XENINTR, "xen_intr", "Xen Interrupt Services");
-
-/*
- * Lock for x86-related structures. Notably modifying
- * xen_intr_auto_vector_count, and allocating interrupts require this lock be
- * held.
- */
-static struct mtx xen_intr_x86_lock;
-
-static u_int first_evtchn_irq;
-
/**
* Per-cpu event channel processing state.
*/
@@ -128,21 +116,8 @@
* Acquire/release operations for isrc->xi_refcount require this lock be held.
*/
static struct mtx xen_intr_isrc_lock;
-static u_int xen_intr_auto_vector_count;
static struct xenisrc *xen_intr_port_to_isrc[NR_EVENT_CHANNELS];
-/*
- * list of released isrcs
- * This is meant to overlay struct xenisrc, with only the xen_arch_isrc_t
- * portion being preserved, everything else can be wiped.
- */
-struct avail_list {
- xen_arch_isrc_t preserve;
- SLIST_ENTRY(avail_list) free;
-};
-static SLIST_HEAD(free, avail_list) avail_list =
- SLIST_HEAD_INITIALIZER(avail_list);
-
/*------------------------- Private Functions --------------------------------*/
/**
@@ -220,64 +195,6 @@
xen_set_bit(port, pcpu->evtchn_enabled);
}
-/**
- * Allocate a Xen interrupt source object.
- *
- * \param type The type of interrupt source to create.
- *
- * \return A pointer to a newly allocated Xen interrupt source
- * object or NULL.
- */
-static struct xenisrc *
-xen_intr_alloc_isrc(void)
-{
- static int warned;
- struct xenisrc *isrc;
- unsigned int vector;
- int error;
-
- mtx_lock(&xen_intr_x86_lock);
- isrc = (struct xenisrc *)SLIST_FIRST(&avail_list);
- if (isrc != NULL) {
- SLIST_REMOVE_HEAD(&avail_list, free);
- mtx_unlock(&xen_intr_x86_lock);
-
- KASSERT(isrc->xi_arch.intsrc.is_pic == &xen_intr_pic,
- ("interrupt not owned by Xen code?"));
-
- KASSERT(isrc->xi_arch.intsrc.is_handlers == 0,
- ("Free evtchn still has handlers"));
-
- return (isrc);
- }
-
- if (xen_intr_auto_vector_count >= NR_EVENT_CHANNELS) {
- if (!warned) {
- warned = 1;
- printf("%s: Xen interrupts exhausted.\n", __func__);
- }
- mtx_unlock(&xen_intr_x86_lock);
- return (NULL);
- }
-
- vector = first_evtchn_irq + xen_intr_auto_vector_count;
- xen_intr_auto_vector_count++;
-
- KASSERT((intr_lookup_source(vector) == NULL),
- ("Trying to use an already allocated vector"));
-
- mtx_unlock(&xen_intr_x86_lock);
- isrc = malloc(sizeof(*isrc), M_XENINTR, M_WAITOK | M_ZERO);
- isrc->xi_arch.intsrc.is_pic = &xen_intr_pic;
- isrc->xi_arch.vector = vector;
- error = intr_register_source(&isrc->xi_arch.intsrc);
- if (error != 0)
- panic("%s(): failed registering interrupt %u, error=%d\n",
- __func__, vector, error);
-
- return (isrc);
-}
-
/**
* Attempt to free an active Xen interrupt source object.
*
@@ -289,8 +206,6 @@
xen_intr_release_isrc(struct xenisrc *isrc)
{
- KASSERT(isrc->xi_arch.intsrc.is_handlers == 0,
- ("Release called, but xenisrc still in use"));
mtx_lock(&xen_intr_isrc_lock);
if (is_valid_evtchn(isrc->xi_port)) {
evtchn_mask_port(isrc->xi_port);
@@ -312,15 +227,7 @@
/* not reachable from xen_intr_port_to_isrc[], unlock */
mtx_unlock(&xen_intr_isrc_lock);
- _Static_assert(sizeof(struct xenisrc) >= sizeof(struct avail_list),
- "unused structure MUST be no larger than in-use structure");
- _Static_assert(offsetof(struct xenisrc, xi_arch) ==
- offsetof(struct avail_list, preserve),
- "unused structure does not properly overlay in-use structure");
-
- mtx_lock(&xen_intr_x86_lock);
- SLIST_INSERT_HEAD(&avail_list, (struct avail_list *)isrc, free);
- mtx_unlock(&xen_intr_x86_lock);
+ xen_arch_intr_release(isrc);
return (0);
}
@@ -361,7 +268,7 @@
}
*port_handlep = NULL;
- isrc = xen_intr_alloc_isrc();
+ isrc = xen_arch_intr_alloc();
if (isrc == NULL)
return (ENOSPC);
@@ -382,7 +289,7 @@
* unless specified otherwise, so shuffle them to balance
* the interrupt load.
*/
- xen_intr_assign_cpu(isrc, apic_cpuid(intr_next_cpu(0)));
+ xen_intr_assign_cpu(isrc, xen_arch_intr_next_cpu(isrc));
}
#endif
@@ -561,8 +468,6 @@
mtx_init(&xen_intr_isrc_lock, "xen-irq-lock", NULL, MTX_DEF);
- mtx_init(&xen_intr_x86_lock, "xen-x86-table-lock", NULL, MTX_DEF);
-
/*
* Set the per-cpu mask of CPU#0 to enable all, since by default all
* event channels are bound to CPU#0.
@@ -585,16 +490,6 @@
}
SYSINIT(xen_intr_init, SI_SUB_INTR, SI_ORDER_SECOND, xen_intr_init, NULL);
-void
-xen_intr_alloc_irqs(void)
-{
-
- if (num_io_irqs > UINT_MAX - NR_EVENT_CHANNELS)
- panic("IRQ allocation overflow (num_msi_irqs too high?)");
- first_evtchn_irq = num_io_irqs;
- num_io_irqs += NR_EVENT_CHANNELS;
-}
-
/*--------------------------- Common PIC Functions ---------------------------*/
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Oct 23, 7:11 PM (3 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24099717
Default Alt Text
D30936.id.diff (10 KB)
Attached To
Mode
D30936: xen/intr: move interrupt allocation/release to architecture
Attached
Detach File
Event Timeline
Log In to Comment