Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143391288
D31188.id107511.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D31188.id107511.diff
View Options
Index: sys/dev/xen/bus/xen_intr.c
===================================================================
--- sys/dev/xen/bus/xen_intr.c
+++ sys/dev/xen/bus/xen_intr.c
@@ -263,7 +263,7 @@
* \return A pointer to a free Xen interrupt source object or NULL.
*/
static struct xenisrc *
-xen_intr_find_unused_isrc(enum evtchn_type type)
+xen_intr_find_unused_isrc(void)
{
int isrc_idx;
@@ -287,7 +287,7 @@
isrc->xi_type == EVTCHN_TYPE_UNBOUND) {
KASSERT(isrc->xi_intsrc.is_handlers == 0,
("Free evtchn still has handlers"));
- isrc->xi_type = type;
+ isrc->xi_type = ~EVTCHN_TYPE_UNBOUND; /* mark allocated */
return (isrc);
}
}
@@ -303,7 +303,7 @@
* object or NULL.
*/
static struct xenisrc *
-xen_intr_alloc_isrc(enum evtchn_type type)
+xen_intr_alloc_isrc(const struct xenisrc *const params)
{
static int warned;
struct xenisrc *isrc;
@@ -311,10 +311,10 @@
int error;
mtx_lock(&xen_intr_isrc_lock);
- isrc = xen_intr_find_unused_isrc(type);
+ isrc = xen_intr_find_unused_isrc();
if (isrc != NULL) {
mtx_unlock(&xen_intr_isrc_lock);
- return (isrc);
+ goto out;
}
if (xen_intr_auto_vector_count >= NR_EVENT_CHANNELS) {
@@ -336,12 +336,16 @@
isrc = malloc(sizeof(*isrc), M_XENINTR, M_WAITOK | M_ZERO);
isrc->xi_intsrc.is_pic = &xen_intr_pic;
isrc->xi_vector = vector;
- isrc->xi_type = type;
+ isrc->xi_type = ~EVTCHN_TYPE_UNBOUND; /* mark allocated */
error = intr_register_source(vector, &isrc->xi_intsrc);
if (error != 0)
panic("%s(): failed registering interrupt %u, error=%d\n",
__func__, vector, error);
+out: ;
+ CTASSERT(offsetof(struct xenisrc, xi_intsrc) == 0);
+ memcpy(&isrc->xi_intsrc + 1, ¶ms->xi_intsrc + 1,
+ sizeof(struct xenisrc) - sizeof(struct intsrc));
return (isrc);
}
@@ -381,7 +385,6 @@
isrc->xi_cpu = 0;
isrc->xi_type = EVTCHN_TYPE_UNBOUND;
isrc->xi_port = INVALID_EVTCHN;
- isrc->xi_cookie = NULL;
mtx_unlock(&xen_intr_isrc_lock);
return (0);
}
@@ -392,8 +395,9 @@
*
* \param isrcp The returned Xen interrupt object associated with
* the specified local port.
- * \param local_port The event channel to bind.
- * \param type The event channel type of local_port.
+ * \param params Template xenisrc which can be used to initialize most
+ * xenisrc fields. Usually BIND_PARAMS() is used to
+ * initialize this.
* \param intr_owner The device making this bind request.
* \param filter An interrupt filter handler. Specify NULL
* to always dispatch to the ithread handler.
@@ -407,15 +411,22 @@
*
* \returns 0 on success, otherwise an errno.
*/
+#define BIND_PARAMS(type, ...) \
+{ \
+ .xi_cookie = NULL, \
+ .xi_type = (type), \
+ __VA_ARGS__ \
+}
static int
-xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
- enum evtchn_type type, const char *intr_owner, driver_filter_t filter,
- driver_intr_t handler, void *arg, enum intr_type flags,
- xen_intr_handle_t *const port_handlep)
+xen_intr_bind_isrc(struct xenisrc **isrcp, const struct xenisrc *const params,
+ const char *intr_owner, driver_filter_t filter, driver_intr_t handler,
+ void *arg, enum intr_type flags, xen_intr_handle_t *const port_handlep)
{
struct xenisrc *isrc;
int error;
+ KASSERT(params != NULL, ("%s: NULL params passed in", __func__));
+
*isrcp = NULL;
if (port_handlep == NULL) {
printf("%s: %s: Bad event handle\n", intr_owner, __func__);
@@ -423,17 +434,23 @@
}
*port_handlep = NULL;
- isrc = xen_intr_alloc_isrc(type);
+ KASSERT((params->xi_type > EVTCHN_TYPE_UNBOUND) &&
+ (params->xi_type < EVTCHN_TYPE_COUNT),
+ ("%s: Called with invalid event channel type (%d)", __func__,
+ params->xi_type));
+
+ isrc = xen_intr_alloc_isrc(params);
if (isrc == NULL)
return (ENOSPC);
- isrc->xi_port = local_port;
refcount_init(&isrc->xi_refcount, 1);
mtx_lock(&xen_intr_isrc_lock);
xen_intr_port_to_isrc[isrc->xi_port] = isrc;
mtx_unlock(&xen_intr_isrc_lock);
+ /* ->xi_cookie is cleared by BIND_PARAMS() */
+
#ifdef SMP
- if (type == EVTCHN_TYPE_PORT) {
+ if (isrc->xi_type == EVTCHN_TYPE_PORT) {
/*
* By default all interrupts are assigned to vCPU#0
* unless specified otherwise, so shuffle them to balance
@@ -994,20 +1011,17 @@
enum intr_type flags, xen_intr_handle_t *port_handlep)
{
struct xenisrc *isrc;
- int error;
-
- error = xen_intr_bind_isrc(&isrc, local_port, EVTCHN_TYPE_PORT,
- device_get_nameunit(dev), filter, handler, arg, flags,
- port_handlep);
- if (error != 0)
- return (error);
-
/*
* The Event Channel API didn't open this port, so it is not
* responsible for closing it automatically on unbind.
*/
- isrc->xi_close = 0;
- return (0);
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT,
+ .xi_close = 0,
+ .xi_port = local_port,
+ );
+
+ return (xen_intr_bind_isrc(&isrc, ¶ms, device_get_nameunit(dev),
+ filter, handler, arg, flags, port_handlep));
}
int
@@ -1016,6 +1030,7 @@
enum intr_type flags, xen_intr_handle_t *port_handlep)
{
struct xenisrc *isrc;
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT);
struct evtchn_alloc_unbound alloc_unbound;
int error;
@@ -1031,9 +1046,9 @@
return (-error);
}
- error = xen_intr_bind_isrc(&isrc, alloc_unbound.port, EVTCHN_TYPE_PORT,
- device_get_nameunit(dev), filter, handler, arg, flags,
- port_handlep);
+ params.xi_port = alloc_unbound.port;
+ error = xen_intr_bind_isrc(&isrc, ¶ms, device_get_nameunit(dev),
+ filter, handler, arg, flags, port_handlep);
if (error != 0) {
evtchn_close_t close = { .port = alloc_unbound.port };
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
@@ -1051,6 +1066,7 @@
void *arg, enum intr_type flags, xen_intr_handle_t *port_handlep)
{
struct xenisrc *isrc;
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT);
struct evtchn_bind_interdomain bind_interdomain;
int error;
@@ -1066,9 +1082,9 @@
return (-error);
}
- error = xen_intr_bind_isrc(&isrc, bind_interdomain.local_port,
- EVTCHN_TYPE_PORT, device_get_nameunit(dev), filter, handler, arg,
- flags, port_handlep);
+ params.xi_port = bind_interdomain.local_port;
+ error = xen_intr_bind_isrc(&isrc, ¶ms, device_get_nameunit(dev),
+ filter, handler, arg, flags, port_handlep);
if (error) {
evtchn_close_t close = { .port = bind_interdomain.local_port };
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
@@ -1091,6 +1107,9 @@
{
u_int vcpu_id = XEN_CPUID_TO_VCPUID(cpu);
struct xenisrc *isrc;
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_VIRQ,
+ .xi_virq = virq,
+ );
struct evtchn_bind_virq bind_virq = { .virq = virq, .vcpu = vcpu_id };
int error;
@@ -1104,9 +1123,9 @@
return (-error);
}
- error = xen_intr_bind_isrc(&isrc, bind_virq.port, EVTCHN_TYPE_VIRQ,
- device_get_nameunit(dev), filter, handler, arg, flags,
- port_handlep);
+ params.xi_port = bind_virq.port;
+ error = xen_intr_bind_isrc(&isrc, ¶ms, device_get_nameunit(dev),
+ filter, handler, arg, flags, port_handlep);
#ifdef SMP
if (error == 0)
@@ -1140,7 +1159,6 @@
* responsible for closing it automatically on unbind.
*/
isrc->xi_close = 1;
- isrc->xi_virq = virq;
return (0);
}
@@ -1152,6 +1170,7 @@
#ifdef SMP
u_int vcpu_id = XEN_CPUID_TO_VCPUID(cpu);
struct xenisrc *isrc;
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_IPI);
struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id };
/* Same size as the one used by intr_handler->ih_name. */
char name[MAXCOMLEN + 1];
@@ -1167,10 +1186,11 @@
return (-error);
}
+ params.xi_port = bind_ipi.port;
snprintf(name, sizeof(name), "cpu%u", cpu);
- error = xen_intr_bind_isrc(&isrc, bind_ipi.port, EVTCHN_TYPE_IPI,
- name, filter, NULL, NULL, flags, port_handlep);
+ error = xen_intr_bind_isrc(&isrc, ¶ms, name, filter, NULL, NULL,
+ flags, port_handlep);
if (error != 0) {
evtchn_close_t close = { .port = bind_ipi.port };
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 30, 8:35 PM (20 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28104086
Default Alt Text
D31188.id107511.diff (7 KB)
Attached To
Mode
D31188: xen/intr: move isrc allocation out of xen_intr_bind_isrc()
Attached
Detach File
Event Timeline
Log In to Comment