From: Jan Beulich <jbeulich@suse.com>
To: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
George Dunlap <George.Dunlap@eu.citrix.com>,
Ian Jackson <iwj@xenproject.org>, Julien Grall <julien@xen.org>,
Wei Liu <wl@xen.org>, Stefano Stabellini <sstabellini@kernel.org>
Subject: [PATCH v5 1/6] evtchn: use per-channel lock where possible
Date: Wed, 27 Jan 2021 09:15:14 +0100 [thread overview]
Message-ID: <081b2253-e445-4242-3f0c-0f2912412d43@suse.com> (raw)
In-Reply-To: <306e62e8-9070-2db9-c959-858465c50c1d@suse.com>
Neither evtchn_status() nor domain_dump_evtchn_info() nor
flask_get_peer_sid() need to hold the per-domain lock - they all only
read a single channel's state (at a time, in the dump case).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
v4: New.
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -974,15 +974,16 @@ int evtchn_status(evtchn_status_t *statu
if ( d == NULL )
return -ESRCH;
- spin_lock(&d->event_lock);
-
if ( !port_is_valid(d, port) )
{
- rc = -EINVAL;
- goto out;
+ rcu_unlock_domain(d);
+ return -EINVAL;
}
chn = evtchn_from_port(d, port);
+
+ evtchn_read_lock(chn);
+
if ( consumer_is_xen(chn) )
{
rc = -EACCES;
@@ -1027,7 +1028,7 @@ int evtchn_status(evtchn_status_t *statu
status->vcpu = chn->notify_vcpu_id;
out:
- spin_unlock(&d->event_lock);
+ evtchn_read_unlock(chn);
rcu_unlock_domain(d);
return rc;
@@ -1582,22 +1583,32 @@ void evtchn_move_pirqs(struct vcpu *v)
static void domain_dump_evtchn_info(struct domain *d)
{
unsigned int port;
- int irq;
printk("Event channel information for domain %d:\n"
"Polling vCPUs: {%*pbl}\n"
" port [p/m/s]\n", d->domain_id, d->max_vcpus, d->poll_mask);
- spin_lock(&d->event_lock);
-
for ( port = 1; port_is_valid(d, port); ++port )
{
- const struct evtchn *chn;
+ struct evtchn *chn;
char *ssid;
+ if ( !(port & 0x3f) )
+ process_pending_softirqs();
+
chn = evtchn_from_port(d, port);
+
+ if ( !evtchn_read_trylock(chn) )
+ {
+ printk(" %4u in flux\n", port);
+ continue;
+ }
+
if ( chn->state == ECS_FREE )
+ {
+ evtchn_read_unlock(chn);
continue;
+ }
printk(" %4u [%d/%d/",
port,
@@ -1607,26 +1618,49 @@ static void domain_dump_evtchn_info(stru
printk("]: s=%d n=%d x=%d",
chn->state, chn->notify_vcpu_id, chn->xen_consumer);
+ ssid = xsm_show_security_evtchn(d, chn);
+
switch ( chn->state )
{
case ECS_UNBOUND:
printk(" d=%d", chn->u.unbound.remote_domid);
break;
+
case ECS_INTERDOMAIN:
printk(" d=%d p=%d",
chn->u.interdomain.remote_dom->domain_id,
chn->u.interdomain.remote_port);
break;
- case ECS_PIRQ:
- irq = domain_pirq_to_irq(d, chn->u.pirq.irq);
- printk(" p=%d i=%d", chn->u.pirq.irq, irq);
+
+ case ECS_PIRQ: {
+ unsigned int pirq = chn->u.pirq.irq;
+
+ /*
+ * The per-channel locks nest inside the per-domain one, so we
+ * can't acquire the latter without first letting go of the former.
+ */
+ evtchn_read_unlock(chn);
+ chn = NULL;
+ if ( spin_trylock(&d->event_lock) )
+ {
+ int irq = domain_pirq_to_irq(d, pirq);
+
+ spin_unlock(&d->event_lock);
+ printk(" p=%u i=%d", pirq, irq);
+ }
+ else
+ printk(" p=%u i=?", pirq);
break;
+ }
+
case ECS_VIRQ:
printk(" v=%d", chn->u.virq);
break;
}
- ssid = xsm_show_security_evtchn(d, chn);
+ if ( chn )
+ evtchn_read_unlock(chn);
+
if (ssid) {
printk(" Z=%s\n", ssid);
xfree(ssid);
@@ -1634,8 +1668,6 @@ static void domain_dump_evtchn_info(stru
printk("\n");
}
}
-
- spin_unlock(&d->event_lock);
}
static void dump_evtchn_info(unsigned char key)
--- a/xen/xsm/flask/flask_op.c
+++ b/xen/xsm/flask/flask_op.c
@@ -555,12 +555,13 @@ static int flask_get_peer_sid(struct xen
struct evtchn *chn;
struct domain_security_struct *dsec;
- spin_lock(&d->event_lock);
-
if ( !port_is_valid(d, arg->evtchn) )
- goto out;
+ return -EINVAL;
chn = evtchn_from_port(d, arg->evtchn);
+
+ evtchn_read_lock(chn);
+
if ( chn->state != ECS_INTERDOMAIN )
goto out;
@@ -573,7 +574,7 @@ static int flask_get_peer_sid(struct xen
rv = 0;
out:
- spin_unlock(&d->event_lock);
+ evtchn_read_unlock(chn);
return rv;
}
next prev parent reply other threads:[~2021-01-27 8:15 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-27 8:13 [PATCH v5 0/6] evtchn: (not so) recent XSAs follow-on Jan Beulich
2021-01-27 8:15 ` Jan Beulich [this message]
2021-01-27 8:16 ` [PATCH v5 2/6] evtchn: convert domain event lock to an r/w one Jan Beulich
2021-05-27 11:01 ` Roger Pau Monné
2021-05-27 11:16 ` Jan Beulich
2022-07-07 18:00 ` Julien Grall
2021-01-27 8:16 ` [PATCH v5 3/6] evtchn: slightly defer lock acquire where possible Jan Beulich
2021-01-27 8:16 ` [PATCH v5 4/6] evtchn: add helper for port_is_valid() + evtchn_from_port() Jan Beulich
2021-01-27 8:17 ` [PATCH v5 5/6] evtchn: type adjustments Jan Beulich
2021-01-27 8:17 ` [PATCH v5 6/6] evtchn: drop acquiring of per-channel lock from send_guest_{global,vcpu}_virq() Jan Beulich
2021-04-21 15:23 ` Ping: [PATCH v5 0/6] evtchn: (not so) recent XSAs follow-on Jan Beulich
2021-04-21 15:56 ` Julien Grall
2021-04-22 8:53 ` Jan Beulich
2021-05-14 15:29 ` Roger Pau Monné
2021-05-17 7:15 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=081b2253-e445-4242-3f0c-0f2912412d43@suse.com \
--to=jbeulich@suse.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=iwj@xenproject.org \
--cc=julien@xen.org \
--cc=sstabellini@kernel.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).