All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Roger Pau Monné" <royger@freebsd.org>
To: Christopher Clark <christopher.w.clark@gmail.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>,
	Wei Liu <wei.liu2@citrix.com>,
	Ross Philipson <ross.philipson@gmail.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	George Dunlap <George.Dunlap@eu.citrix.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Jason Andryuk <jandryuk@gmail.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	Julien Grall <julien.grall@arm.com>, Tim Deegan <tim@xen.org>,
	Daniel Smith <dpsmith@apertussolutions.com>,
	Rich Persaud <persaur@gmail.com>,
	Paul Durrant <paul.durrant@citrix.com>,
	Jan Beulich <jbeulich@suse.com>,
	xen-devel <xen-devel@lists.xenproject.org>,
	James McKenzie <james@bromium.com>,
	Eric Chanudet <eric.chanudet@gmail.com>,
	Roger Pau Monne <roger.pau@citrix.com>
Subject: Re: [PATCH v3 04/15] argo: init, destroy and soft-reset, with enable command line opt
Date: Thu, 10 Jan 2019 11:19:41 +0100	[thread overview]
Message-ID: <CAPLaKK6z4eNtJx+X3RdTcO8tKb+PxaeBwA_N3wDmbXc7Qss58A@mail.gmail.com> (raw)
In-Reply-To: <1546846968-7372-5-git-send-email-christopher.w.clark@gmail.com>

 aOn Mon, Jan 7, 2019 at 8:44 AM Christopher Clark
<christopher.w.clark@gmail.com> wrote:
>
> Initialises basic data structures and performs teardown of argo state
> for domain shutdown.
>
> Inclusion of the Argo implementation is dependent on CONFIG_ARGO.
>
> Introduces a new Xen command line parameter 'argo': bool to enable/disable
> the argo hypercall. Defaults to disabled.
>
> New headers:
>   public/argo.h: with definions of addresses and ring structure, including
>   indexes for atomic update for communication between domain and hypervisor.
>
>   xen/argo.h: to expose the hooks for integration into domain lifecycle:
>     argo_init: per-domain init of argo data structures for domain_create.
>     argo_destroy: teardown for domain_destroy and the error exit
>                   path of domain_create.
>     argo_soft_reset: reset of domain state for domain_soft_reset.
>
> Adds two new fields to struct domain:
>     rwlock_t argo_lock;
>     struct argo_domain *argo;
>
> In accordance with recent work on _domain_destroy, argo_destroy is
> idempotent. It will tear down: all rings registered by this domain, all
> rings where this domain is the single sender (ie. specified partner,
> non-wildcard rings), and all pending notifications where this domain is
> awaiting signal about available space in the rings of other domains.
>
> A count will be maintained of the number of rings that a domain has
> registered in order to limit it below the fixed maximum limit defined here.
>
> The software license on the public header is the BSD license, standard
> procedure for the public Xen headers. The public header was originally
> posted under a GPL license at: [1]:
> https://lists.xenproject.org/archives/html/xen-devel/2013-05/msg02710.html
>
> The following ACK by Lars Kurth is to confirm that only people being
> employees of Citrix contributed to the header files in the series posted at
> [1] and that thus the copyright of the files in question is fully owned by
> Citrix. The ACK also confirms that Citrix is happy for the header files to
> be published under a BSD license in this series (which is based on [1]).
>
> Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com>
> Acked-by: Lars Kurth <lars.kurth@citrix.com>
> ---
> v2 rewrite locking explanation comment
> v2 header copyright line now includes 2019
> v2 self: use ring_info backpointer in pending_ent to maintain npending
> v2 self: rename all_rings_remove_info to domain_rings_remove_all
> v2 feedback Jan: drop cookie, implement teardown
> v2 self: add npending to track number of pending entries per ring
> v2 self: amend comment on locking; drop section comments
> v2 cookie_eq: test low bits first and use likely on high bits
> v2 self: OVERHAUL
> v2 self: s/argo_pending_ent/pending_ent/g
> v2 self: drop pending_remove_ent, inline at single call site
> v1 feedback Roger, Jan: drop argo prefix on static functions
> v2 #4 Lars: add Acked-by and details to commit message.
> v2 feedback #9 Jan: document argo boot opt in xen-command-line.markdown
> v2 bugfix: xsm use in soft-reset prior to introduction
> v2 feedback #9 Jan: drop 'message' from do_argo_message_op
> v1 #5 feedback Paul: init/destroy unsigned, brackets and whitespace fixes
> v1 #5 feedback Paul: Use mfn_eq for comparing mfns.
> v1 #5 feedback Paul: init/destroy : use currd
> v1 #6 (#5) feedback Jan: init/destroy: s/ENOSYS/EOPNOTSUPP/
> v1 #6 feedback Paul: Folded patch 6 into patch 5.
> v1 #6 feedback Jan: drop opt_argo_enabled initializer
> v1 $6 feedback Jan: s/ENOSYS/EOPNOTSUPP/g and drop useless dprintk
> v1. #5 feedback Paul: change the license on public header to BSD
> - ack from Lars at Citrix.
> v1. self, Jan: drop unnecessary xen include from sched.h
> v1. self, Jan: drop inclusion of public argo.h in private one
> v1. self, Jan: add include of public argo.h to argo.c
> v1. self, Jan: drop fwd decl of argo_domain in priv header
> v1. Paul/self/Jan: add data structures to xlat.lst and compat/argo.h to Makefile
> v1. self: removed allocation of event channel since switching to VIRQ
> v1. self: drop types.h include from private argo.h
> v1: reorder public argo include position
> v1: #13 feedback Jan: public namespace: prefix with xen
> v1: self: rename pending ent "id" to "domain_id"
> v1: self: add domain_cookie to ent struct
> v1. #15 feedback Jan: make cmd unsigned
> v1. #15 feedback Jan: make i loop variable unsigned
> v1: self: adjust dprintks in init, destroy
> v1: #18 feedback Jan: meld max ring count limit
> v1: self: use type not struct in public defn, affects compat gen header
> v1: feedback #15 Jan: handle upper-halves of hypercall args
> v1: add comment explaining the 'magic' field
> v1: self + Jan feedback: implement soft reset
> v1: feedback #13 Roger: use ASSERT_UNREACHABLE
>
>  docs/misc/xen-command-line.pandoc |  11 +
>  xen/common/argo.c                 | 461 +++++++++++++++++++++++++++++++++++++-
>  xen/common/domain.c               |  20 ++
>  xen/include/Makefile              |   1 +
>  xen/include/public/argo.h         |  59 +++++
>  xen/include/xen/argo.h            |  23 ++
>  xen/include/xen/sched.h           |   6 +
>  xen/include/xlat.lst              |   2 +
>  8 files changed, 582 insertions(+), 1 deletion(-)
>  create mode 100644 xen/include/public/argo.h
>  create mode 100644 xen/include/xen/argo.h
>
> diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
> index a755a67..aea13eb 100644
> --- a/docs/misc/xen-command-line.pandoc
> +++ b/docs/misc/xen-command-line.pandoc
> @@ -182,6 +182,17 @@ Permit Xen to use "Always Running APIC Timer" support on compatible hardware
>  in combination with cpuidle.  This option is only expected to be useful for
>  developers wishing Xen to fall back to older timing methods on newer hardware.
>
> +### argo
> +> `= <boolean>`
> +
> +> Default: `false`
> +
> +Enable the Argo hypervisor-mediated interdomain communication mechanism.
> +
> +This allows domains access to the Argo hypercall, which supports registration
> +of memory rings with the hypervisor to receive messages, sending messages to
> +other domains by hypercall and querying the ring status of other domains.
> +
>  ### asid (x86)
>  > `= <boolean>`
>
> diff --git a/xen/common/argo.c b/xen/common/argo.c
> index 6f782f7..86195d3 100644
> --- a/xen/common/argo.c
> +++ b/xen/common/argo.c
> @@ -17,7 +17,177 @@
>   */
>
>  #include <xen/errno.h>
> +#include <xen/sched.h>
> +#include <xen/domain.h>
> +#include <xen/argo.h>
> +#include <xen/event.h>
> +#include <xen/domain_page.h>
>  #include <xen/guest_access.h>
> +#include <xen/time.h>
> +#include <public/argo.h>

We usually try to sort header includes alphabetically, and I would add
a newline between the xen/* and the public/* header includes.

> +
> +DEFINE_XEN_GUEST_HANDLE(xen_argo_addr_t);
> +DEFINE_XEN_GUEST_HANDLE(xen_argo_ring_t);
> +
> +/* Xen command line option to enable argo */
> +static bool __read_mostly opt_argo_enabled;
> +boolean_param("argo", opt_argo_enabled);

I would drop the opt_* prefix, new options added recently don't
include the prefix already.

> +
> +typedef struct argo_ring_id
> +{
> +    uint32_t port;
> +    domid_t partner_id;
> +    domid_t domain_id;
> +} argo_ring_id;
> +
> +/* Data about a domain's own ring that it has registered */
> +struct argo_ring_info
> +{
> +    /* next node in the hash, protected by L2 */
> +    struct hlist_node node;
> +    /* this ring's id, protected by L2 */
> +    struct argo_ring_id id;
> +    /* L3 */
> +    spinlock_t lock;
> +    /* length of the ring, protected by L3 */
> +    uint32_t len;
> +    /* number of pages in the ring, protected by L3 */
> +    uint32_t npage;

Can you infer number of pages form the length of the ring, or the
other way around?

I'm not sure why both need to be stored here.

> +    /* number of pages translated into mfns, protected by L3 */
> +    uint32_t nmfns;
> +    /* cached tx pointer location, protected by L3 */
> +    uint32_t tx_ptr;

All this fields are not part of any public structure, so I wonder if
it would be better to simply use unsigned int for those, or size_t.

> +    /* mapped ring pages protected by L3 */
> +    uint8_t **mfn_mapping;

Why 'uint8_t *', wouldn't it be better to just use 'void *' if it's a mapping?

> +    /* list of mfns of guest ring, protected by L3 */
> +    mfn_t *mfns;
> +    /* list of struct pending_ent for this ring, protected by L3 */
> +    struct hlist_head pending;
> +    /* number of pending entries queued for this ring, protected by L3 */
> +    uint32_t npending;
> +};
> +
> +/* Data about a single-sender ring, held by the sender (partner) domain */
> +struct argo_send_info
> +{
> +    /* next node in the hash, protected by Lsend */
> +    struct hlist_node node;
> +    /* this ring's id, protected by Lsend */
> +    struct argo_ring_id id;
> +};
> +
> +/* A space-available notification that is awaiting sufficient space */
> +struct pending_ent
> +{
> +    /* List node within argo_ring_info's pending list */
> +    struct hlist_node node;
> +    /*
> +     * List node within argo_domain's wildcard_pend_list. Only used if the
> +     * ring is one with a wildcard partner (ie. that any domain may send to)
> +     * to enable cancelling signals on wildcard rings on domain destroy.
> +     */
> +    struct hlist_node wildcard_node;
> +    /*
> +     * Pointer to the ring_info that this ent pertains to. Used to ensure that
> +     * ring_info->npending is decremented when ents for wildcard rings are
> +     * cancelled for domain destroy.
> +     * Caution: Must hold the correct locks before accessing ring_info via this.
> +     */
> +    struct argo_ring_info *ring_info;
> +    /* domain to be notified when space is available */
> +    domid_t domain_id;
> +    uint16_t pad;

No need for the pad in internal structures.

> +    /* minimum ring space available that this signal is waiting upon */
> +    uint32_t len;
> +};
> +
> +/*
> + * The value of the argo element in a struct domain is
> + * protected by the global lock argo_lock: L1
> + */
> +#define ARGO_HTABLE_SIZE 32
> +struct argo_domain
> +{
> +    /* L2 */
> +    rwlock_t lock;
> +    /*
> +     * Hash table of argo_ring_info about rings this domain has registered.
> +     * Protected by L2.
> +     */
> +    struct hlist_head ring_hash[ARGO_HTABLE_SIZE];
> +    /* Counter of rings registered by this domain. Protected by L2. */
> +    uint32_t ring_count;
> +
> +    /* Lsend */
> +    spinlock_t send_lock;
> +    /*
> +     * Hash table of argo_send_info about rings other domains have registered
> +     * for this domain to send to. Single partner, non-wildcard rings.
> +     * Protected by Lsend.
> +     */
> +    struct hlist_head send_hash[ARGO_HTABLE_SIZE];
> +
> +    /* Lwildcard */
> +    spinlock_t wildcard_lock;
> +    /*
> +     * List of pending space-available signals for this domain about wildcard
> +     * rings registered by other domains. Protected by Lwildcard.
> +     */
> +    struct hlist_head wildcard_pend_list;
> +};
> +
> +/*
> + * Locking is organized as follows:
> + *
> + * Terminology: R(<lock>) means taking a read lock on the specified lock;
> + *              W(<lock>) means taking a write lock on it.
> + *
> + * L1 : The global lock: argo_lock
> + * Protects the argo elements of all struct domain *d in the system.
> + * It does not protect any of the elements of d->argo, only their
> + * addresses.
> + *
> + * By extension since the destruction of a domain with a non-NULL
> + * d->argo will need to free the d->argo pointer, holding W(L1)
> + * guarantees that no domains pointers that argo is interested in
> + * become invalid whilst this lock is held.
> + */
> +
> +static DEFINE_RWLOCK(argo_lock); /* L1 */

You also add an argo_lock to each domain struct which doesn't seem to
be mentioned here at all. Shouldn't that lock be the one that protects
d->argo? (instead of this global lock?)

> +
> +/*
> + * L2 : The per-domain ring hash lock: d->argo->lock
> + * Holding a read lock on L2 protects the ring hash table and
> + * the elements in the hash_table d->argo->ring_hash, and
> + * the node and id fields in struct argo_ring_info in the
> + * hash table.
> + * Holding a write lock on L2 protects all of the elements of
> + * struct argo_ring_info.
> + *
> + * To take L2 you must already have R(L1). W(L1) implies W(L2) and L3.
> + *
> + * L3 : The ringinfo lock: argo_ring_info *ringinfo; ringinfo->lock
> + * Protects all the fields within the argo_ring_info, aside from the ones that
> + * L2 already protects: node, id, lock.
> + *
> + * To aquire L3 you must already have R(L2). W(L2) implies L3.
> + *
> + * Lsend : The per-domain single-sender partner rings lock: d->argo->send_lock
> + * Protects the per-domain send hash table : d->argo->send_hash
> + * and the elements in the hash table, and the node and id fields
> + * in struct argo_send_info in the hash table.
> + *
> + * To take Lsend, you must already have R(L1). W(L1) implies Lsend.
> + * Do not attempt to acquire a L2 on any domain after taking and while
> + * holding a Lsend lock -- acquire the L2 (if one is needed) beforehand.
> + *
> + * Lwildcard : The per-domain wildcard pending list lock: d->argo->wildcard_lock
> + * Protects the per-domain list of outstanding signals for space availability
> + * on wildcard rings.
> + *
> + * To take Lwildcard, you must already have R(L1). W(L1) implies Lwildcard.
> + * No other locks are acquired after obtaining Lwildcard.
> + */

IMO I think the locking is overly complicated, and there's no
reasoning why so many locks are needed. Wouldn't it be enough to start
with a single lock that protects the whole d->argo existence and
contents?

I would start with a very simple (as simple as possible) locking
structure and go improving from there if there are performance
bottlenecks.

>  /* Change this to #define ARGO_DEBUG here to enable more debug messages */
>  #undef ARGO_DEBUG
> @@ -28,10 +198,299 @@
>  #define argo_dprintk(format, ... ) ((void)0)
>  #endif
>
> +static void
> +ring_unmap(struct argo_ring_info *ring_info)
> +{
> +    unsigned int i;
> +
> +    if ( !ring_info->mfn_mapping )
> +        return;
> +
> +    for ( i = 0; i < ring_info->nmfns; i++ )
> +    {
> +        if ( !ring_info->mfn_mapping[i] )
> +            continue;
> +        if ( ring_info->mfns )
> +            argo_dprintk(XENLOG_ERR "argo: unmapping page %"PRI_mfn" from %p\n",
> +                         mfn_x(ring_info->mfns[i]),
> +                         ring_info->mfn_mapping[i]);
> +        unmap_domain_page_global(ring_info->mfn_mapping[i]);
> +        ring_info->mfn_mapping[i] = NULL;
> +    }

As noted in another patch, I would consider mapping this in contiguous
virtual address space using vmap, but I'm not going to insist.

> +}
> +
> +static void
> +wildcard_pending_list_remove(domid_t domain_id, struct pending_ent *ent)
> +{
> +    struct domain *d = get_domain_by_id(domain_id);

Newline.

> +    if ( !d )
> +        return;
> +
> +    if ( d->argo )

Don't you need to pick d->argo_lock here to prevent d->argo from being
removed under your feet?

> +    {
> +        spin_lock(&d->argo->wildcard_lock);
> +        hlist_del(&ent->wildcard_node);
> +        spin_unlock(&d->argo->wildcard_lock);
> +    }
> +    put_domain(d);
> +}
> +
> +static void
> +pending_remove_all(struct argo_ring_info *ring_info)
> +{
> +    struct hlist_node *node, *next;
> +    struct pending_ent *ent;
> +
> +    hlist_for_each_entry_safe(ent, node, next, &ring_info->pending, node)

As a side note, it might be interesting to introduce a helper like
hlist_first_entry_or_null, that would remove the need to have an extra
*next element, and would be the more natural way to drain a hlist
(seeing that you have the same pattern in
wildcard_rings_pending_remove).

> +    {
> +        if ( ring_info->id.partner_id == XEN_ARGO_DOMID_ANY )
> +            wildcard_pending_list_remove(ent->domain_id, ent);
> +        hlist_del(&ent->node);
> +        xfree(ent);
> +    }
> +    ring_info->npending = 0;
> +}
> +
> +static void
> +wildcard_rings_pending_remove(struct domain *d)
> +{
> +    struct hlist_node *node, *next;
> +    struct pending_ent *ent;
> +
> +    ASSERT(rw_is_write_locked(&argo_lock));
> +
> +    hlist_for_each_entry_safe(ent, node, next, &d->argo->wildcard_pend_list,
> +                              node)
> +    {
> +        hlist_del(&ent->node);
> +        ent->ring_info->npending--;
> +        hlist_del(&ent->wildcard_node);
> +        xfree(ent);
> +    }
> +}
> +
> +static void
> +ring_remove_mfns(const struct domain *d, struct argo_ring_info *ring_info)
> +{
> +    unsigned int i;
> +
> +    ASSERT(rw_is_write_locked(&d->argo->lock) ||
> +           rw_is_write_locked(&argo_lock));

I think the above requires a comment of why two different locks are
used to protect the ring mfns, and why just having one of them locked
is enough.

> +
> +    if ( !ring_info->mfns )
> +        return;
> +
> +    if ( !ring_info->mfn_mapping )
> +    {
> +        ASSERT_UNREACHABLE();
> +        return;
> +    }
> +
> +    ring_unmap(ring_info);
> +
> +    for ( i = 0; i < ring_info->nmfns; i++ )
> +        if ( !mfn_eq(ring_info->mfns[i], INVALID_MFN) )
> +            put_page_and_type(mfn_to_page(ring_info->mfns[i]));
> +
> +    xfree(ring_info->mfns);
> +    ring_info->mfns = NULL;

Xen has a handly macro for this, XFREE. That would free the memory and
assign the pointer to NULL.

> +    ring_info->npage = 0;
> +    xfree(ring_info->mfn_mapping);
> +    ring_info->mfn_mapping = NULL;
> +    ring_info->nmfns = 0;
> +}
> +
> +static void
> +ring_remove_info(struct domain *d, struct argo_ring_info *ring_info)

I think the domain parameter can be constifyed here, since it's only
used by ring_remove_mfnsnd that function already expects a const
domain struct.

> +{
> +    ASSERT(rw_is_write_locked(&d->argo->lock) ||
> +           rw_is_write_locked(&argo_lock));
> +
> +    pending_remove_all(ring_info);
> +    hlist_del(&ring_info->node);
> +    ring_remove_mfns(d, ring_info);
> +    xfree(ring_info);
> +}
> +
> +static void
> +domain_rings_remove_all(struct domain *d)
> +{
> +    unsigned int i;
> +
> +    for ( i = 0; i < ARGO_HTABLE_SIZE; ++i )
> +    {
> +        struct hlist_node *node, *next;
> +        struct argo_ring_info *ring_info;
> +
> +        hlist_for_each_entry_safe(ring_info, node, next,
> +                                  &d->argo->ring_hash[i], node)
> +            ring_remove_info(d, ring_info);
> +    }
> +    d->argo->ring_count = 0;
> +}
> +
> +/*
> + * Tear down all rings of other domains where src_d domain is the partner.
> + * (ie. it is the single domain that can send to those rings.)
> + * This will also cancel any pending notifications about those rings.
> + */
> +static void
> +partner_rings_remove(struct domain *src_d)
> +{
> +    unsigned int i;
> +
> +    ASSERT(rw_is_write_locked(&argo_lock));
> +
> +    for ( i = 0; i < ARGO_HTABLE_SIZE; ++i )
> +    {
> +        struct hlist_node *node, *next;
> +        struct argo_send_info *send_info;
> +
> +        hlist_for_each_entry_safe(send_info, node, next,
> +                                  &src_d->argo->send_hash[i], node)
> +        {
> +            struct argo_ring_info *ring_info;
> +            struct domain *dst_d;
> +
> +            dst_d = get_domain_by_id(send_info->id.domain_id);
> +            if ( dst_d )
> +            {
> +                ring_info = ring_find_info(dst_d, &send_info->id);
> +                if ( ring_info )
> +                {
> +                    ring_remove_info(dst_d, ring_info);
> +                    dst_d->argo->ring_count--;
> +                }
> +
> +                put_domain(dst_d);
> +            }
> +
> +            hlist_del(&send_info->node);
> +            xfree(send_info);
> +        }
> +    }
> +}
> +
>  long
>  do_argo_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) arg1,
>             XEN_GUEST_HANDLE_PARAM(void) arg2, unsigned long arg3,
>             unsigned long arg4)
>  {
> -    return -ENOSYS;
> +    struct domain *currd = current->domain;
> +    long rc = -EFAULT;
> +
> +    argo_dprintk("->do_argo_op(%u,%p,%p,%d,%d)\n", cmd,
> +                 (void *)arg1.p, (void *)arg2.p, (int) arg3, (int) arg4);
> +
> +    if ( unlikely(!opt_argo_enabled) )
> +    {
> +        rc = -EOPNOTSUPP;
> +        return rc;

Why not just 'return -EOPNOTSUPP;'?

> +    }
> +
> +    domain_lock(currd);
> +
> +    switch (cmd)
> +    {
> +    default:
> +        rc = -EOPNOTSUPP;
> +        break;
> +    }
> +
> +    domain_unlock(currd);
> +
> +    argo_dprintk("<-do_argo_op(%u)=%ld\n", cmd, rc);
> +
> +    return rc;
> +}
> +
> +static void
> +argo_domain_init(struct argo_domain *argo)
> +{
> +    unsigned int i;
> +
> +    rwlock_init(&argo->lock);
> +    spin_lock_init(&argo->send_lock);
> +    spin_lock_init(&argo->wildcard_lock);
> +    argo->ring_count = 0;
> +
> +    for ( i = 0; i < ARGO_HTABLE_SIZE; ++i )
> +    {
> +        INIT_HLIST_HEAD(&argo->ring_hash[i]);
> +        INIT_HLIST_HEAD(&argo->send_hash[i]);
> +    }
> +    INIT_HLIST_HEAD(&argo->wildcard_pend_list);
> +}
> +
> +int
> +argo_init(struct domain *d)
> +{
> +    struct argo_domain *argo;
> +
> +    if ( !opt_argo_enabled )
> +    {
> +        argo_dprintk("argo disabled, domid: %d\n", d->domain_id);
> +        return 0;
> +    }
> +
> +    argo_dprintk("init: domid: %d\n", d->domain_id);
> +
> +    argo = xmalloc(struct argo_domain);
> +    if ( !argo )
> +        return -ENOMEM;
> +
> +    write_lock(&argo_lock);
> +
> +    argo_domain_init(argo);
> +
> +    d->argo = argo;

Where's the d->argo_lock initialization?

> +
> +    write_unlock(&argo_lock);
> +
> +    return 0;
> +}
> +
> +void
> +argo_destroy(struct domain *d)
> +{
> +    BUG_ON(!d->is_dying);
> +
> +    write_lock(&argo_lock);
> +
> +    argo_dprintk("destroy: domid %d d->argo=%p\n", d->domain_id, d->argo);
> +
> +    if ( d->argo )
> +    {
> +        domain_rings_remove_all(d);
> +        partner_rings_remove(d);
> +        wildcard_rings_pending_remove(d);
> +        xfree(d->argo);
> +        d->argo = NULL;
> +    }
> +    write_unlock(&argo_lock);
> +}
> +
> +void
> +argo_soft_reset(struct domain *d)
> +{
> +    write_lock(&argo_lock);
> +
> +    argo_dprintk("soft reset d=%d d->argo=%p\n", d->domain_id, d->argo);
> +
> +    if ( d->argo )
> +    {
> +        domain_rings_remove_all(d);
> +        partner_rings_remove(d);
> +        wildcard_rings_pending_remove(d);
> +
> +        if ( !opt_argo_enabled )
> +        {
> +            xfree(d->argo);
> +            d->argo = NULL;

Can opt_argo_enabled change during runtime?

> +        }
> +        else
> +            argo_domain_init(d->argo);
> +    }
> +
> +    write_unlock(&argo_lock);
>  }
> diff --git a/xen/common/domain.c b/xen/common/domain.c
> index c623dae..9596840 100644
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -32,6 +32,7 @@
>  #include <xen/grant_table.h>
>  #include <xen/xenoprof.h>
>  #include <xen/irq.h>
> +#include <xen/argo.h>
>  #include <asm/debugger.h>
>  #include <asm/p2m.h>
>  #include <asm/processor.h>
> @@ -277,6 +278,10 @@ static void _domain_destroy(struct domain *d)
>
>      xfree(d->pbuf);
>
> +#ifdef CONFIG_ARGO
> +    argo_destroy(d);
> +#endif

Instead of adding such ifdefs you could provide dummy argo_destroy
inline functions in argo.h when CONFIG_ARGO is not set.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2019-01-10 10:19 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-07  7:42 [PATCH v3 00/15] Argo: hypervisor-mediated interdomain communication Christopher Clark
2019-01-07  7:42 ` [PATCH v3 01/15] argo: Introduce the Kconfig option to govern inclusion of Argo Christopher Clark
2019-01-08 15:46   ` Jan Beulich
2019-01-07  7:42 ` [PATCH v3 02/15] argo: introduce the argo_op hypercall boilerplate Christopher Clark
2019-01-07  7:42 ` [PATCH v3 03/15] argo: define argo_dprintk for subsystem debugging Christopher Clark
2019-01-08 15:50   ` Jan Beulich
2019-01-10  9:28   ` Roger Pau Monné
2019-01-07  7:42 ` [PATCH v3 04/15] argo: init, destroy and soft-reset, with enable command line opt Christopher Clark
2019-01-08 22:08   ` Ross Philipson
2019-01-08 22:23     ` Christopher Clark
2019-01-08 22:54   ` Jason Andryuk
2019-01-09  6:48     ` Christopher Clark
2019-01-09 14:15       ` Jason Andryuk
2019-01-09 23:24         ` Christopher Clark
2019-01-09  9:35     ` Jan Beulich
2019-01-09 14:26       ` Jason Andryuk
2019-01-09 14:38         ` Jan Beulich
2019-01-10 23:29           ` Christopher Clark
2019-01-10 10:19   ` Roger Pau Monné [this message]
2019-01-10 11:52     ` Jan Beulich
2019-01-10 12:26       ` Roger Pau Monné
2019-01-10 12:46         ` Jan Beulich
2019-01-11  6:03     ` Christopher Clark
2019-01-11  9:27       ` Roger Pau Monné
2019-01-14  8:32         ` Christopher Clark
2019-01-14 11:32           ` Roger Pau Monné
2019-01-14 14:28             ` Rich Persaud
2019-01-10 16:16   ` Eric Chanudet
2019-01-11  6:05     ` Christopher Clark
2019-01-11 11:54   ` Jan Beulich
2019-01-14  8:33     ` Christopher Clark
2019-01-14 14:46   ` Wei Liu
2019-01-14 15:29     ` Lars Kurth
2019-01-14 18:16     ` Christopher Clark
2019-01-14 19:42     ` Roger Pau Monné
2019-02-04 20:56     ` Christopher Clark
2019-02-05 10:32       ` Wei Liu
2019-01-14 14:58   ` Andrew Cooper
2019-01-14 15:12     ` Jan Beulich
2019-01-15  7:24       ` Christopher Clark
2019-01-15  7:21     ` Christopher Clark
2019-01-15  9:01       ` Jan Beulich
2019-01-15  9:06         ` Andrew Cooper
2019-01-15  9:17           ` Jan Beulich
2019-01-07  7:42 ` [PATCH v3 05/15] errno: add POSIX error codes EMSGSIZE, ECONNREFUSED to the ABI Christopher Clark
2019-01-07  7:42 ` [PATCH v3 06/15] xen/arm: introduce guest_handle_for_field() Christopher Clark
2019-01-08 22:03   ` Stefano Stabellini
2019-01-07  7:42 ` [PATCH v3 07/15] argo: implement the register op Christopher Clark
2019-01-09 15:55   ` Wei Liu
2019-01-09 16:00     ` Christopher Clark
2019-01-09 17:02       ` Julien Grall
2019-01-09 17:18         ` Stefano Stabellini
2019-01-09 18:13           ` Julien Grall
2019-01-09 20:33             ` Christopher Clark
2019-01-09 17:54         ` Wei Liu
2019-01-09 18:28           ` Julien Grall
2019-01-09 20:38             ` Christopher Clark
2019-01-10 11:24   ` Roger Pau Monné
2019-01-10 11:57     ` Jan Beulich
2019-01-11  6:30       ` Christopher Clark
2019-01-11  6:29     ` Christopher Clark
2019-01-11  9:38       ` Roger Pau Monné
2019-01-10 20:11   ` Eric Chanudet
2019-01-11  6:09     ` Christopher Clark
2019-01-14 14:19   ` Jan Beulich
2019-01-15  7:56     ` Christopher Clark
2019-01-15  8:36       ` Jan Beulich
2019-01-15  8:46         ` Christopher Clark
2019-01-14 15:31   ` Andrew Cooper
2019-01-15  8:02     ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 08/15] argo: implement the unregister op Christopher Clark
2019-01-10 11:40   ` Roger Pau Monné
2019-01-15  8:05     ` Christopher Clark
2019-01-14 15:06   ` Jan Beulich
2019-01-15  8:11     ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 09/15] argo: implement the sendv op; evtchn: expose send_guest_global_virq Christopher Clark
2019-01-09 18:05   ` Jason Andryuk
2019-01-10  2:08     ` Christopher Clark
2019-01-09 18:57   ` Roger Pau Monné
2019-01-10  3:09     ` Christopher Clark
2019-01-10 12:01       ` Roger Pau Monné
2019-01-10 12:13         ` Jan Beulich
2019-01-10 12:40           ` Roger Pau Monné
2019-01-10 12:53             ` Jan Beulich
2019-01-11  6:37               ` Christopher Clark
2019-01-10 21:41   ` Eric Chanudet
2019-01-11  7:12     ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 10/15] argo: implement the notify op Christopher Clark
2019-01-10 12:21   ` Roger Pau Monné
2019-01-15  6:53     ` Christopher Clark
2019-01-15  8:06       ` Roger Pau Monné
2019-01-15  8:32         ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 11/15] xsm, argo: XSM control for argo register Christopher Clark
2019-01-07  7:42 ` [PATCH v3 12/15] xsm, argo: XSM control for argo message send operation Christopher Clark
2019-01-07  7:42 ` [PATCH v3 13/15] xsm, argo: XSM control for any access to argo by a domain Christopher Clark
2019-01-07  7:42 ` [PATCH v3 14/15] xsm, argo: notify: don't describe rings that cannot be sent to Christopher Clark
2019-01-07  7:42 ` [PATCH v3 15/15] argo: validate hypercall arg structures via compat machinery Christopher Clark
2019-01-14 12:57   ` Jan Beulich
2019-01-17  7:22     ` Christopher Clark
2019-01-17 11:25       ` Jan Beulich
2019-01-20 21:18         ` Christopher Clark
2019-01-21 12:03           ` Jan Beulich
2019-01-22 11:08             ` Jan Beulich
2019-01-23 21:14               ` Christopher Clark

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=CAPLaKK6z4eNtJx+X3RdTcO8tKb+PxaeBwA_N3wDmbXc7Qss58A@mail.gmail.com \
    --to=royger@freebsd.org \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=christopher.w.clark@gmail.com \
    --cc=dpsmith@apertussolutions.com \
    --cc=eric.chanudet@gmail.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=james@bromium.com \
    --cc=jandryuk@gmail.com \
    --cc=jbeulich@suse.com \
    --cc=julien.grall@arm.com \
    --cc=konrad.wilk@oracle.com \
    --cc=paul.durrant@citrix.com \
    --cc=persaur@gmail.com \
    --cc=roger.pau@citrix.com \
    --cc=ross.philipson@gmail.com \
    --cc=sstabellini@kernel.org \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --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 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.