Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151945881
D31188.id104982.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D31188.id104982.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
@@ -200,7 +200,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;
@@ -224,7 +224,7 @@
isrc->xi_type == EVTCHN_TYPE_UNBOUND) {
KASSERT(!xen_arch_intr_has_handlers(isrc),
("Free evtchn still has handlers"));
- isrc->xi_type = type;
+ isrc->xi_type = EVTCHN_TYPE_COUNT; /* mark allocated */
return (isrc);
}
}
@@ -240,7 +240,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;
@@ -248,10 +248,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) {
@@ -273,12 +273,16 @@
isrc = malloc(sizeof(*isrc), M_XENINTR, M_WAITOK | M_ZERO);
isrc->xi_arch.intsrc.is_pic = &xen_intr_pic;
isrc->xi_arch.vector = vector;
- isrc->xi_type = type;
+ isrc->xi_type = EVTCHN_TYPE_COUNT; /* mark allocated */
error = intr_register_source(&isrc->xi_arch.intsrc);
if (error != 0)
panic("%s(): failed registering interrupt %u, error=%d\n",
__func__, vector, error);
+out: ;
+ CTASSERT(offsetof(struct xenisrc, xi_arch) == 0);
+ memcpy(&isrc->xi_arch + 1, ¶ms->xi_arch + 1,
+ sizeof(struct xenisrc) - sizeof(xen_arch_isrc_t));
return (isrc);
}
@@ -318,7 +322,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);
}
@@ -329,8 +332,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.
@@ -344,11 +348,16 @@
*
* \returns 0 on success, otherwise an errno.
*/
+#define BIND_PARAMS(type, ...) \
+{ \
+ .xi_type = (type), \
+ .xi_cookie = NULL, \
+ __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 *port_handlep)
+xen_intr_bind_isrc(struct xenisrc **isrcp, const struct xenisrc *params,
+ const char *intr_owner, driver_filter_t filter, driver_intr_t handler,
+ void *arg, enum intr_type flags, xen_intr_handle_t *port_handlep)
{
struct xenisrc *isrc;
int error;
@@ -359,10 +368,9 @@
return (EINVAL);
}
- isrc = xen_intr_alloc_isrc(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;
@@ -371,8 +379,10 @@
/* Assign the opaque handler */
*port_handlep = xen_intr_handle_from_isrc(isrc);
+ /* ->xi_cookie is cleared in 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
@@ -838,20 +848,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);
+ struct xenisrc params = BIND_PARAMS(EVTCHN_TYPE_PORT,
+ .xi_port = local_port,
+ /*
+ * The Event Channel API didn't open this port, so it is not
+ * responsible for closing it automatically on unbind.
+ */
+ .xi_close = 0,
+ );
- /*
- * 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);
+ return (xen_intr_bind_isrc(&isrc, ¶ms, device_get_nameunit(dev),
+ filter, handler, arg, flags, port_handlep));
}
int
@@ -860,6 +867,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;
@@ -875,11 +883,11 @@
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 };
+ evtchn_close_t close = { .port = params.xi_port };
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
panic("EVTCHNOP_close failed");
return (error);
@@ -895,6 +903,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;
@@ -910,11 +919,11 @@
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 };
+ evtchn_close_t close = { .port = params.xi_port };
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
panic("EVTCHNOP_close failed");
return (error);
@@ -935,6 +944,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;
@@ -948,9 +960,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)
@@ -958,7 +970,7 @@
#endif
if (error != 0) {
- evtchn_close_t close = { .port = bind_virq.port };
+ evtchn_close_t close = { .port = params.xi_port };
xen_intr_unbind(*port_handlep);
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
@@ -983,7 +995,6 @@
* responsible for closing it automatically on unbind.
*/
isrc->xi_close = 1;
- isrc->xi_virq = virq;
return (0);
}
@@ -995,6 +1006,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];
@@ -1010,12 +1022,13 @@
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 };
+ evtchn_close_t close = { .port = params.xi_port };
xen_intr_unbind(*port_handlep);
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 12, 4:44 PM (16 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31359439
Default Alt Text
D31188.id104982.diff (8 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