]> xenbits.xensource.com Git - people/pauldu/xen.git/commitdiff
evtchn: let evtchn_set_priority() acquire the per-channel lock
authorJan Beulich <jbeulich@suse.com>
Fri, 23 Oct 2020 08:12:31 +0000 (10:12 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 23 Oct 2020 08:12:31 +0000 (10:12 +0200)
Some lock wants to be held to make sure the port doesn't change state,
but there's no point holding the per-domain event lock here. Switch to
using the finer grained per-channel lock instead (albeit as a downside
for the time being this requires disabling interrupts for a short
period of time).

FAOD this doesn't guarantee anything towards in particular
evtchn_fifo_set_pending(), as for interdomain channels that function
would be called with the remote side's per-channel lock held.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
xen/common/event_channel.c

index 37d0b753849181d94f2c5ebdb7e21bb5c1d8679c..cd4a2c05018e69f1346f7817d06f3db2b5a71bff 100644 (file)
@@ -1154,20 +1154,17 @@ static long evtchn_set_priority(const struct evtchn_set_priority *set_priority)
 {
     struct domain *d = current->domain;
     unsigned int port = set_priority->port;
+    struct evtchn *chn;
     long ret;
-
-    spin_lock(&d->event_lock);
+    unsigned long flags;
 
     if ( !port_is_valid(d, port) )
-    {
-        spin_unlock(&d->event_lock);
         return -EINVAL;
-    }
 
-    ret = evtchn_port_set_priority(d, evtchn_from_port(d, port),
-                                   set_priority->priority);
-
-    spin_unlock(&d->event_lock);
+    chn = evtchn_from_port(d, port);
+    spin_lock_irqsave(&chn->lock, flags);
+    ret = evtchn_port_set_priority(d, chn, set_priority->priority);
+    spin_unlock_irqrestore(&chn->lock, flags);
 
     return ret;
 }