Page MenuHomeFreeBSD

D31188.id107511.diff
No OneTemporary

D31188.id107511.diff

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, &params->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, &params, 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, &params, 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, &params, 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, &params, 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, &params, name, filter, NULL, NULL,
+ flags, port_handlep);
if (error != 0) {
evtchn_close_t close = { .port = bind_ipi.port };

File Metadata

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)

Event Timeline