All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] domain referencing adjustments
@ 2021-01-05 13:23 Jan Beulich
  2021-01-05 13:24 ` [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id() Jan Beulich
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Jan Beulich @ 2021-01-05 13:23 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, George Dunlap, Ian Jackson, Julien Grall,
	Stefano Stabellini, Wei Liu

In the course of preparing v4 of "evtchn: (not so) recent XSAs follow-on"
(which is a contextual prereq to some of the patches here) I've noticed
some slight inefficiencies. I've then also looked for similar patterns
elsewhere.

1: common: don't (kind of) open-code rcu_lock_domain_by_any_id()
2: evtchn: don't pointlessly use get_domain()
3: argo: don't pointlessly use get_domain_by_id()
4: x86: don't pointlessly use get_domain_by_id()
5: x86/mem-sharing: don't pointlessly use get_domain_by_id()

Jan


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id()
  2021-01-05 13:23 [PATCH 0/5] domain referencing adjustments Jan Beulich
@ 2021-01-05 13:24 ` Jan Beulich
  2021-01-05 13:38   ` Andrew Cooper
  2021-01-05 13:24 ` [PATCH 2/5] evtchn: don't pointlessly use get_domain() Jan Beulich
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2021-01-05 13:24 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, George Dunlap, Ian Jackson, Julien Grall,
	Stefano Stabellini, Wei Liu

Even more so when using rcu_lock_domain_by_id() in place of the more
efficient rcu_lock_current_domain().

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
Besides get_pg_owner(), gnttab_copy_lock_domain() has similar strange(?)
behavior: They accept DOMID_SELF, but not the resolved ID of the caller.
---
v4: New.

--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -353,10 +353,7 @@ static int evtchn_bind_interdomain(evtch
     evtchn_port_t  rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
 
-    if ( rdom == DOMID_SELF )
-        rdom = current->domain->domain_id;
-
-    if ( (rd = rcu_lock_domain_by_id(rdom)) == NULL )
+    if ( (rd = rcu_lock_domain_by_any_id(rdom)) == NULL )
         return -ESRCH;
 
     write_lock(&ld->event_lock);
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -2568,12 +2568,6 @@ struct domain *get_pg_owner(domid_t domi
 {
     struct domain *pg_owner = NULL, *curr = current->domain;
 
-    if ( likely(domid == DOMID_SELF) )
-    {
-        pg_owner = rcu_lock_current_domain();
-        goto out;
-    }
-
     if ( unlikely(domid == curr->domain_id) )
     {
         gdprintk(XENLOG_WARNING, "Cannot specify itself as foreign domain\n");
@@ -2591,7 +2585,7 @@ struct domain *get_pg_owner(domid_t domi
         break;
 
     default:
-        if ( (pg_owner = rcu_lock_domain_by_id(domid)) == NULL )
+        if ( (pg_owner = rcu_lock_domain_by_any_id(domid)) == NULL )
             gdprintk(XENLOG_WARNING, "Unknown domain d%d\n", domid);
         break;
     }



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/5] evtchn: don't pointlessly use get_domain()
  2021-01-05 13:23 [PATCH 0/5] domain referencing adjustments Jan Beulich
  2021-01-05 13:24 ` [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id() Jan Beulich
@ 2021-01-05 13:24 ` Jan Beulich
  2021-01-05 13:26 ` [PATCH 3/5] argo: don't pointlessly use get_domain_by_id() Jan Beulich
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2021-01-05 13:24 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, George Dunlap, Ian Jackson, Julien Grall,
	Stefano Stabellini, Wei Liu

For short-lived references rcu_lock_domain() is the better (slightly
cheaper) alternative.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -642,7 +642,7 @@ int evtchn_close(struct domain *d1, int
              */
             write_unlock(&chn1->lock);
             write_unlock(&chn2->lock);
-            put_domain(d2);
+            rcu_unlock_domain(d2);
             chn2 = NULL;
         }
 
@@ -677,7 +677,7 @@ int evtchn_close(struct domain *d1, int
              */
             write_unlock(&chn1->lock);
             write_unlock(&chn2->lock);
-            put_domain(d2);
+            rcu_unlock_domain(d2);
             chn2 = NULL;
         }
 
@@ -725,9 +725,8 @@ int evtchn_close(struct domain *d1, int
 
         if ( !chn2 )
         {
-            /* If we unlock chn1 then we could lose d2. Must get a reference. */
-            if ( unlikely(!get_domain(d2)) )
-                BUG();
+            /* If we unlock chn1 then we could lose d2. */
+            rcu_lock_domain(d2);
 
             chn2 = _evtchn_from_port(d2, chn1->u.interdomain.remote_port);
             BUG_ON(!chn2);
@@ -778,7 +777,7 @@ int evtchn_close(struct domain *d1, int
          */
         write_unlock(&chn1->lock);
         write_unlock(&chn2->lock);
-        put_domain(d2);
+        rcu_unlock_domain(d2);
     }
 
     write_unlock(&d1->event_lock);



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/5] argo: don't pointlessly use get_domain_by_id()
  2021-01-05 13:23 [PATCH 0/5] domain referencing adjustments Jan Beulich
  2021-01-05 13:24 ` [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id() Jan Beulich
  2021-01-05 13:24 ` [PATCH 2/5] evtchn: don't pointlessly use get_domain() Jan Beulich
@ 2021-01-05 13:26 ` Jan Beulich
  2021-01-13 22:24   ` Christopher Clark
  2021-01-05 13:26 ` [PATCH 4/5] x86: " Jan Beulich
  2021-01-05 13:28 ` [PATCH 5/5] x86/mem-sharing: " Jan Beulich
  4 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2021-01-05 13:26 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap, Christopher Clark

For short-lived references rcu_lock_domain_by_id() is the better
(slightly cheaper) alternative.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
Is it really intentional for fill_ring_data() to return success (0) in
case the domain can't be found or has argo disabled? Even if so, the
uninitialized ent.max_message_size will be leaked to the caller then
(and similarly when find_ring_info_by_match() returns NULL). Perhaps
the field should only be copied back when ent.flags is non-zero?

--- a/xen/common/argo.c
+++ b/xen/common/argo.c
@@ -445,13 +445,13 @@ signal_domain(struct domain *d)
 static void
 signal_domid(domid_t domain_id)
 {
-    struct domain *d = get_domain_by_id(domain_id);
+    struct domain *d = rcu_lock_domain_by_id(domain_id);
 
     if ( !d )
         return;
 
     signal_domain(d);
-    put_domain(d);
+    rcu_unlock_domain(d);
 }
 
 static void
@@ -983,7 +983,7 @@ ringbuf_insert(const struct domain *d, s
 static void
 wildcard_pending_list_remove(domid_t domain_id, struct pending_ent *ent)
 {
-    struct domain *d = get_domain_by_id(domain_id);
+    struct domain *d = rcu_lock_domain_by_id(domain_id);
 
     if ( !d )
         return;
@@ -996,13 +996,13 @@ wildcard_pending_list_remove(domid_t dom
         list_del(&ent->wildcard_node);
         spin_unlock(&d->argo->wildcard_L2_lock);
     }
-    put_domain(d);
+    rcu_unlock_domain(d);
 }
 
 static void
 wildcard_pending_list_insert(domid_t domain_id, struct pending_ent *ent)
 {
-    struct domain *d = get_domain_by_id(domain_id);
+    struct domain *d = rcu_lock_domain_by_id(domain_id);
 
     if ( !d )
         return;
@@ -1015,7 +1015,7 @@ wildcard_pending_list_insert(domid_t dom
         list_add(&ent->wildcard_node, &d->argo->wildcard_pend_list);
         spin_unlock(&d->argo->wildcard_L2_lock);
     }
-    put_domain(d);
+    rcu_unlock_domain(d);
 }
 
 static void
@@ -1283,7 +1283,7 @@ partner_rings_remove(struct domain *src_
                                                       struct argo_send_info,
                                                       node)) )
         {
-            struct domain *dst_d = get_domain_by_id(send_info->id.domain_id);
+            struct domain *dst_d = rcu_lock_domain_by_id(send_info->id.domain_id);
 
             if ( dst_d && dst_d->argo )
             {
@@ -1302,7 +1302,7 @@ partner_rings_remove(struct domain *src_
                 ASSERT_UNREACHABLE();
 
             if ( dst_d )
-                put_domain(dst_d);
+                rcu_unlock_domain(dst_d);
 
             list_del(&send_info->node);
             xfree(send_info);
@@ -1330,7 +1330,7 @@ fill_ring_data(const struct domain *curr
 
     ent.flags = 0;
 
-    dst_d = get_domain_by_id(ent.ring.domain_id);
+    dst_d = rcu_lock_domain_by_id(ent.ring.domain_id);
     if ( !dst_d || !dst_d->argo )
         goto out;
 
@@ -1340,10 +1340,7 @@ fill_ring_data(const struct domain *curr
      */
     ret = xsm_argo_send(currd, dst_d);
     if ( ret )
-    {
-        put_domain(dst_d);
-        return ret;
-    }
+        goto out;
 
     read_lock(&dst_d->argo->rings_L2_rwlock);
 
@@ -1405,7 +1402,7 @@ fill_ring_data(const struct domain *curr
 
  out:
     if ( dst_d )
-        put_domain(dst_d);
+        rcu_unlock_domain(dst_d);
 
     if ( !ret && (__copy_field_to_guest(data_ent_hnd, &ent, flags) ||
                   __copy_field_to_guest(data_ent_hnd, &ent, max_message_size)) )
@@ -1569,7 +1566,7 @@ unregister_ring(struct domain *currd,
     if ( ring_id.partner_id == XEN_ARGO_DOMID_ANY )
         goto out;
 
-    dst_d = get_domain_by_id(ring_id.partner_id);
+    dst_d = rcu_lock_domain_by_id(ring_id.partner_id);
     if ( !dst_d || !dst_d->argo )
     {
         ASSERT_UNREACHABLE();
@@ -1592,7 +1589,7 @@ unregister_ring(struct domain *currd,
     read_unlock(&L1_global_argo_rwlock);
 
     if ( dst_d )
-        put_domain(dst_d);
+        rcu_unlock_domain(dst_d);
 
     xfree(send_info);
 
@@ -1663,7 +1660,7 @@ register_ring(struct domain *currd,
     }
     else
     {
-        dst_d = get_domain_by_id(reg.partner_id);
+        dst_d = rcu_lock_domain_by_id(reg.partner_id);
         if ( !dst_d )
         {
             argo_dprintk("!dst_d, ESRCH\n");
@@ -1845,7 +1842,7 @@ register_ring(struct domain *currd,
 
  out:
     if ( dst_d )
-        put_domain(dst_d);
+        rcu_unlock_domain(dst_d);
 
     if ( ret )
         xfree(send_info);
@@ -1988,7 +1985,7 @@ sendv(struct domain *src_d, xen_argo_add
     src_id.domain_id = src_d->domain_id;
     src_id.partner_id = dst_addr->domain_id;
 
-    dst_d = get_domain_by_id(dst_addr->domain_id);
+    dst_d = rcu_lock_domain_by_id(dst_addr->domain_id);
     if ( !dst_d )
         return -ESRCH;
 
@@ -1998,7 +1995,7 @@ sendv(struct domain *src_d, xen_argo_add
         gprintk(XENLOG_ERR, "argo: XSM REJECTED %i -> %i\n",
                 src_d->domain_id, dst_d->domain_id);
 
-        put_domain(dst_d);
+        rcu_unlock_domain(dst_d);
 
         return ret;
     }
@@ -2068,7 +2065,7 @@ sendv(struct domain *src_d, xen_argo_add
         signal_domain(dst_d);
 
     if ( dst_d )
-        put_domain(dst_d);
+        rcu_unlock_domain(dst_d);
 
     return ( ret < 0 ) ? ret : len;
 }



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/5] x86: don't pointlessly use get_domain_by_id()
  2021-01-05 13:23 [PATCH 0/5] domain referencing adjustments Jan Beulich
                   ` (2 preceding siblings ...)
  2021-01-05 13:26 ` [PATCH 3/5] argo: don't pointlessly use get_domain_by_id() Jan Beulich
@ 2021-01-05 13:26 ` Jan Beulich
  2021-01-05 13:28 ` [PATCH 5/5] x86/mem-sharing: " Jan Beulich
  4 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2021-01-05 13:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, George Dunlap, Wei Liu, Roger Pau Monné

For short-lived references rcu_lock_domain_by_id() is the better
(slightly cheaper) alternative.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/cpu/mcheck/mcaction.c
+++ b/xen/arch/x86/cpu/mcheck/mcaction.c
@@ -87,7 +87,7 @@ mc_memerr_dhandler(struct mca_binfo *bin
             BUG_ON( bank->mc_domid == DOMID_COW );
             if ( bank->mc_domid != DOMID_XEN )
             {
-                d = get_domain_by_id(bank->mc_domid);
+                d = rcu_lock_domain_by_id(bank->mc_domid);
                 ASSERT(d);
                 gfn = get_gpfn_from_mfn((bank->mc_addr) >> PAGE_SHIFT);
 
@@ -132,6 +132,8 @@ mc_memerr_dhandler(struct mca_binfo *bin
                     goto vmce_failed;
                 }
 
+                rcu_unlock_domain(d);
+
                 /*
                  * Impacted domain go on with domain's recovery job
                  * if the domain has its own MCA handler.
@@ -139,12 +141,11 @@ mc_memerr_dhandler(struct mca_binfo *bin
                  * its own recovery job.
                  */
                 *result = MCER_RECOVERED;
-                put_domain(d);
 
                 return;
 vmce_failed:
-                put_domain(d);
                 domain_crash(d);
+                rcu_unlock_domain(d);
             }
         }
     }
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -1497,7 +1497,6 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_m
 
         if ( mc_msrinject->mcinj_flags & MC_MSRINJ_F_GPADDR )
         {
-            domid_t domid;
             struct domain *d;
             struct mcinfo_msr *msr;
             unsigned int i;
@@ -1505,17 +1504,17 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_m
             unsigned long gfn, mfn;
             p2m_type_t t;
 
-            domid = (mc_msrinject->mcinj_domid == DOMID_SELF) ?
-                    current->domain->domain_id : mc_msrinject->mcinj_domid;
-            if ( domid >= DOMID_FIRST_RESERVED )
-                return x86_mcerr("do_mca inject: incompatible flag "
-                                 "MC_MSRINJ_F_GPADDR with domain %d",
-                                 -EINVAL, domid);
-
-            d = get_domain_by_id(domid);
+            d = rcu_lock_domain_by_any_id(mc_msrinject->mcinj_domid);
             if ( d == NULL )
+            {
+                if ( mc_msrinject->mcinj_domid >= DOMID_FIRST_RESERVED )
+                    return x86_mcerr("do_mca inject: incompatible flag "
+                                     "MC_MSRINJ_F_GPADDR with domain %d",
+                                     -EINVAL, domid);
+
                 return x86_mcerr("do_mca inject: bad domain id %d",
                                  -EINVAL, domid);
+            }
 
             for ( i = 0, msr = &mc_msrinject->mcinj_msr[0];
                   i < mc_msrinject->mcinj_count;
@@ -1528,7 +1527,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_m
                 if ( mfn == mfn_x(INVALID_MFN) )
                 {
                     put_gfn(d, gfn);
-                    put_domain(d);
+                    rcu_unlock_domain(d);
                     return x86_mcerr("do_mca inject: bad gfn %#lx of domain %d",
                                      -EINVAL, gfn, domid);
                 }
@@ -1538,7 +1537,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_m
                 put_gfn(d, gfn);
             }
 
-            put_domain(d);
+            rcu_unlock_domain(d);
         }
 
         if ( !x86_mc_msrinject_verify(mc_msrinject) )
--- a/xen/arch/x86/debug.c
+++ b/xen/arch/x86/debug.c
@@ -164,13 +164,13 @@ unsigned int dbg_rw_mem(void * __user ad
                         unsigned int len, domid_t domid, bool toaddr,
                         uint64_t pgd3)
 {
-        struct domain *d = get_domain_by_id(domid);
+    struct domain *d = rcu_lock_domain_by_id(domid);
 
     if ( d )
     {
         if ( !d->is_dying )
             len = dbg_rw_guest_mem(d, addr, buf, len, toaddr, pgd3);
-        put_domain(d);
+        rcu_unlock_domain(d);
     }
 
     return len;
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -323,7 +323,7 @@ void destroy_irq(unsigned int irq)
 
     if ( desc->arch.creator_domid != DOMID_INVALID )
     {
-        struct domain *d = get_domain_by_id(desc->arch.creator_domid);
+        struct domain *d = rcu_lock_domain_by_id(desc->arch.creator_domid);
 
         if ( d )
         {
@@ -334,7 +334,7 @@ void destroy_irq(unsigned int irq)
                        "Could not revoke %pd access to IRQ%u (error %d)\n",
                        d, irq, err);
 
-            put_domain(d);
+            rcu_unlock_domain(d);
         }
 
         desc->arch.creator_domid = DOMID_INVALID;



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 5/5] x86/mem-sharing: don't pointlessly use get_domain_by_id()
  2021-01-05 13:23 [PATCH 0/5] domain referencing adjustments Jan Beulich
                   ` (3 preceding siblings ...)
  2021-01-05 13:26 ` [PATCH 4/5] x86: " Jan Beulich
@ 2021-01-05 13:28 ` Jan Beulich
  2021-01-05 13:37   ` Tamas K Lengyel
  4 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2021-01-05 13:28 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, George Dunlap, Wei Liu, Roger Pau Monné,
	Tamas K Lengyel

For short-lived references rcu_lock_domain_by_id() is the better
(slightly cheaper) alternative.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -537,7 +537,7 @@ static int audit(void)
             p2m_type_t t;
             mfn_t o_mfn;
 
-            d = get_domain_by_id(g->domain);
+            d = rcu_lock_domain_by_id(g->domain);
             if ( d == NULL )
             {
                 gdprintk(XENLOG_ERR,
@@ -562,7 +562,7 @@ static int audit(void)
                          d, g->gfn, mfn_x(mfn), p2m_ram_shared, t);
                 errors++;
             }
-            put_domain(d);
+            rcu_unlock_domain(d);
             nr_gfns++;
         }
         /* The type count has an extra ref because we have locked the page */
@@ -1043,10 +1043,10 @@ static int share_pages(struct domain *sd
         rmap_del(gfn, cpage, 0);
         rmap_add(gfn, spage);
         put_count++;
-        d = get_domain_by_id(gfn->domain);
+        d = rcu_lock_domain_by_id(gfn->domain);
         BUG_ON(!d);
         BUG_ON(set_shared_p2m_entry(d, gfn->gfn, smfn));
-        put_domain(d);
+        rcu_unlock_domain(d);
     }
     ASSERT(list_empty(&cpage->sharing->gfns));
     BUG_ON(!put_count);


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 5/5] x86/mem-sharing: don't pointlessly use get_domain_by_id()
  2021-01-05 13:28 ` [PATCH 5/5] x86/mem-sharing: " Jan Beulich
@ 2021-01-05 13:37   ` Tamas K Lengyel
  0 siblings, 0 replies; 11+ messages in thread
From: Tamas K Lengyel @ 2021-01-05 13:37 UTC (permalink / raw)
  To: Jan Beulich
  Cc: xen-devel, Andrew Cooper, George Dunlap, Wei Liu, Roger Pau Monné

On Tue, Jan 5, 2021 at 8:28 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> For short-lived references rcu_lock_domain_by_id() is the better
> (slightly cheaper) alternative.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Acked-by: Tamas K Lengyel <tamas@tklengyel.com>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id()
  2021-01-05 13:24 ` [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id() Jan Beulich
@ 2021-01-05 13:38   ` Andrew Cooper
  2021-01-05 14:17     ` Jan Beulich
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Cooper @ 2021-01-05 13:38 UTC (permalink / raw)
  To: Jan Beulich, xen-devel
  Cc: George Dunlap, Ian Jackson, Julien Grall, Stefano Stabellini, Wei Liu

On 05/01/2021 13:24, Jan Beulich wrote:
> Even more so when using rcu_lock_domain_by_id() in place of the more
> efficient rcu_lock_current_domain().
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>

> ---
> Besides get_pg_owner(), gnttab_copy_lock_domain() has similar strange(?)
> behavior: They accept DOMID_SELF, but not the resolved ID of the caller.

I queried that behaviour years and years ago.

According to Keir, it is part of the attempt to force guests to not know
their own domid.  Xen itself does (or did) its very hardest to prevent a
domU knowing its own domid, while at the same time the "domid" key in
xenstore is mandatory for setting up PV rings.

I'd personally think was a short sighted move.

~Andrew


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id()
  2021-01-05 13:38   ` Andrew Cooper
@ 2021-01-05 14:17     ` Jan Beulich
  2021-01-13 22:42       ` Andrew Cooper
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2021-01-05 14:17 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: George Dunlap, Ian Jackson, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On 05.01.2021 14:38, Andrew Cooper wrote:
> On 05/01/2021 13:24, Jan Beulich wrote:
>> Even more so when using rcu_lock_domain_by_id() in place of the more
>> efficient rcu_lock_current_domain().
>>
>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> 
> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>

Thanks.

>> ---
>> Besides get_pg_owner(), gnttab_copy_lock_domain() has similar strange(?)
>> behavior: They accept DOMID_SELF, but not the resolved ID of the caller.
> 
> I queried that behaviour years and years ago.
> 
> According to Keir, it is part of the attempt to force guests to not know
> their own domid.  Xen itself does (or did) its very hardest to prevent a
> domU knowing its own domid, while at the same time the "domid" key in
> xenstore is mandatory for setting up PV rings.
> 
> I'd personally think was a short sighted move.

Let me make another patch then, unless you can see reasons we should
stick to the current behavior. Figuring out its own domid is possible
for a domain, after all, and even shouldn't be overly difficult.

Jan


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/5] argo: don't pointlessly use get_domain_by_id()
  2021-01-05 13:26 ` [PATCH 3/5] argo: don't pointlessly use get_domain_by_id() Jan Beulich
@ 2021-01-13 22:24   ` Christopher Clark
  0 siblings, 0 replies; 11+ messages in thread
From: Christopher Clark @ 2021-01-13 22:24 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, George Dunlap

On Tue, Jan 5, 2021 at 5:26 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> For short-lived references rcu_lock_domain_by_id() is the better
> (slightly cheaper) alternative.

This should scale better than the existing use of get_domain_by_id.

I actually found it pretty hard to study the code for the effects of
switching over to use the RCU domain reference logic, and I would have
been happier with reviewing if I'd been able to exercise it with some
focused testing; XTF needs support for tests with multiple test VMs to
enable Argo tests of communication and interactions with hypervisor
state.

> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Acked-by: Christopher Clark <christopher.w.clark@gmail.com>

> ---
> Is it really intentional for fill_ring_data() to return success (0) in
> case the domain can't be found or has argo disabled?

Good question; I think this logic can and should be improved. I will
work on a patch.

> Even if so, the
> uninitialized ent.max_message_size will be leaked to the caller then
> (and similarly when find_ring_info_by_match() returns NULL). Perhaps
> the field should only be copied back when ent.flags is non-zero?

Yes.

thanks,

Christopher

>
> --- a/xen/common/argo.c
> +++ b/xen/common/argo.c
> @@ -445,13 +445,13 @@ signal_domain(struct domain *d)
>  static void
>  signal_domid(domid_t domain_id)
>  {
> -    struct domain *d = get_domain_by_id(domain_id);
> +    struct domain *d = rcu_lock_domain_by_id(domain_id);
>
>      if ( !d )
>          return;
>
>      signal_domain(d);
> -    put_domain(d);
> +    rcu_unlock_domain(d);
>  }
>
>  static void
> @@ -983,7 +983,7 @@ ringbuf_insert(const struct domain *d, s
>  static void
>  wildcard_pending_list_remove(domid_t domain_id, struct pending_ent *ent)
>  {
> -    struct domain *d = get_domain_by_id(domain_id);
> +    struct domain *d = rcu_lock_domain_by_id(domain_id);
>
>      if ( !d )
>          return;
> @@ -996,13 +996,13 @@ wildcard_pending_list_remove(domid_t dom
>          list_del(&ent->wildcard_node);
>          spin_unlock(&d->argo->wildcard_L2_lock);
>      }
> -    put_domain(d);
> +    rcu_unlock_domain(d);
>  }
>
>  static void
>  wildcard_pending_list_insert(domid_t domain_id, struct pending_ent *ent)
>  {
> -    struct domain *d = get_domain_by_id(domain_id);
> +    struct domain *d = rcu_lock_domain_by_id(domain_id);
>
>      if ( !d )
>          return;
> @@ -1015,7 +1015,7 @@ wildcard_pending_list_insert(domid_t dom
>          list_add(&ent->wildcard_node, &d->argo->wildcard_pend_list);
>          spin_unlock(&d->argo->wildcard_L2_lock);
>      }
> -    put_domain(d);
> +    rcu_unlock_domain(d);
>  }
>
>  static void
> @@ -1283,7 +1283,7 @@ partner_rings_remove(struct domain *src_
>                                                        struct argo_send_info,
>                                                        node)) )
>          {
> -            struct domain *dst_d = get_domain_by_id(send_info->id.domain_id);
> +            struct domain *dst_d = rcu_lock_domain_by_id(send_info->id.domain_id);
>
>              if ( dst_d && dst_d->argo )
>              {
> @@ -1302,7 +1302,7 @@ partner_rings_remove(struct domain *src_
>                  ASSERT_UNREACHABLE();
>
>              if ( dst_d )
> -                put_domain(dst_d);
> +                rcu_unlock_domain(dst_d);
>
>              list_del(&send_info->node);
>              xfree(send_info);
> @@ -1330,7 +1330,7 @@ fill_ring_data(const struct domain *curr
>
>      ent.flags = 0;
>
> -    dst_d = get_domain_by_id(ent.ring.domain_id);
> +    dst_d = rcu_lock_domain_by_id(ent.ring.domain_id);
>      if ( !dst_d || !dst_d->argo )
>          goto out;
>
> @@ -1340,10 +1340,7 @@ fill_ring_data(const struct domain *curr
>       */
>      ret = xsm_argo_send(currd, dst_d);
>      if ( ret )
> -    {
> -        put_domain(dst_d);
> -        return ret;
> -    }
> +        goto out;
>
>      read_lock(&dst_d->argo->rings_L2_rwlock);
>
> @@ -1405,7 +1402,7 @@ fill_ring_data(const struct domain *curr
>
>   out:
>      if ( dst_d )
> -        put_domain(dst_d);
> +        rcu_unlock_domain(dst_d);
>
>      if ( !ret && (__copy_field_to_guest(data_ent_hnd, &ent, flags) ||
>                    __copy_field_to_guest(data_ent_hnd, &ent, max_message_size)) )
> @@ -1569,7 +1566,7 @@ unregister_ring(struct domain *currd,
>      if ( ring_id.partner_id == XEN_ARGO_DOMID_ANY )
>          goto out;
>
> -    dst_d = get_domain_by_id(ring_id.partner_id);
> +    dst_d = rcu_lock_domain_by_id(ring_id.partner_id);
>      if ( !dst_d || !dst_d->argo )
>      {
>          ASSERT_UNREACHABLE();
> @@ -1592,7 +1589,7 @@ unregister_ring(struct domain *currd,
>      read_unlock(&L1_global_argo_rwlock);
>
>      if ( dst_d )
> -        put_domain(dst_d);
> +        rcu_unlock_domain(dst_d);
>
>      xfree(send_info);
>
> @@ -1663,7 +1660,7 @@ register_ring(struct domain *currd,
>      }
>      else
>      {
> -        dst_d = get_domain_by_id(reg.partner_id);
> +        dst_d = rcu_lock_domain_by_id(reg.partner_id);
>          if ( !dst_d )
>          {
>              argo_dprintk("!dst_d, ESRCH\n");
> @@ -1845,7 +1842,7 @@ register_ring(struct domain *currd,
>
>   out:
>      if ( dst_d )
> -        put_domain(dst_d);
> +        rcu_unlock_domain(dst_d);
>
>      if ( ret )
>          xfree(send_info);
> @@ -1988,7 +1985,7 @@ sendv(struct domain *src_d, xen_argo_add
>      src_id.domain_id = src_d->domain_id;
>      src_id.partner_id = dst_addr->domain_id;
>
> -    dst_d = get_domain_by_id(dst_addr->domain_id);
> +    dst_d = rcu_lock_domain_by_id(dst_addr->domain_id);
>      if ( !dst_d )
>          return -ESRCH;
>
> @@ -1998,7 +1995,7 @@ sendv(struct domain *src_d, xen_argo_add
>          gprintk(XENLOG_ERR, "argo: XSM REJECTED %i -> %i\n",
>                  src_d->domain_id, dst_d->domain_id);
>
> -        put_domain(dst_d);
> +        rcu_unlock_domain(dst_d);
>
>          return ret;
>      }
> @@ -2068,7 +2065,7 @@ sendv(struct domain *src_d, xen_argo_add
>          signal_domain(dst_d);
>
>      if ( dst_d )
> -        put_domain(dst_d);
> +        rcu_unlock_domain(dst_d);
>
>      return ( ret < 0 ) ? ret : len;
>  }
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id()
  2021-01-05 14:17     ` Jan Beulich
@ 2021-01-13 22:42       ` Andrew Cooper
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Cooper @ 2021-01-13 22:42 UTC (permalink / raw)
  To: Jan Beulich
  Cc: George Dunlap, Ian Jackson, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On 05/01/2021 14:17, Jan Beulich wrote:
>>> ---
>>> Besides get_pg_owner(), gnttab_copy_lock_domain() has similar strange(?)
>>> behavior: They accept DOMID_SELF, but not the resolved ID of the caller.
>> I queried that behaviour years and years ago.
>>
>> According to Keir, it is part of the attempt to force guests to not know
>> their own domid.  Xen itself does (or did) its very hardest to prevent a
>> domU knowing its own domid, while at the same time the "domid" key in
>> xenstore is mandatory for setting up PV rings.
>>
>> I'd personally think was a short sighted move.
> Let me make another patch then, unless you can see reasons we should
> stick to the current behavior. Figuring out its own domid is possible
> for a domain, after all, and even shouldn't be overly difficult.

I don't see any reason to keep these semantics, other than the general
argument against relaxing things vs compatibility with older hypervisors.

I honestly can't make up my mind, so whichever you prefer.

~Andrew


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-01-13 22:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-05 13:23 [PATCH 0/5] domain referencing adjustments Jan Beulich
2021-01-05 13:24 ` [PATCH 1/5] common: don't (kind of) open-code rcu_lock_domain_by_any_id() Jan Beulich
2021-01-05 13:38   ` Andrew Cooper
2021-01-05 14:17     ` Jan Beulich
2021-01-13 22:42       ` Andrew Cooper
2021-01-05 13:24 ` [PATCH 2/5] evtchn: don't pointlessly use get_domain() Jan Beulich
2021-01-05 13:26 ` [PATCH 3/5] argo: don't pointlessly use get_domain_by_id() Jan Beulich
2021-01-13 22:24   ` Christopher Clark
2021-01-05 13:26 ` [PATCH 4/5] x86: " Jan Beulich
2021-01-05 13:28 ` [PATCH 5/5] x86/mem-sharing: " Jan Beulich
2021-01-05 13:37   ` Tamas K Lengyel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.