[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 08/12] x86/hvm/ioreq: maintain an array of ioreq servers rather than a list
On Tue, Sep 05, 2017 at 12:37:12PM +0100, Paul Durrant wrote: > A subsequent patch will remove the current implicit limitation on creation > of ioreq servers which is due to the allocation of gfns for the ioreq > structures and buffered ioreq ring. > > It will therefore be necessary to introduce an explicit limit and, since > this limit should be small, it simplifies the code to maintain an array of > that size rather than using a list. > > Also, by reserving an array slot for the default server and populating > array slots early in create, the need to pass an 'is_default' boolean > to sub-functions can be avoided. > > Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> LGTM, just a couple of nitpicks, I think they can be fixed upon commit if desired. Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> > --- > Cc: Jan Beulich <jbeulich@xxxxxxxx> > Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > > v4: > - Introduced more helper macros and relocated them to the top of the > code. > > v3: > - New patch (replacing "move is_default into struct hvm_ioreq_server") in > response to review comments. > --- > xen/arch/x86/hvm/ioreq.c | 491 > ++++++++++++++++++--------------------- > xen/include/asm-x86/hvm/domain.h | 11 +- > 2 files changed, 235 insertions(+), 267 deletions(-) > > diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c > index f2e0b3f74a..287572bd1f 100644 > --- a/xen/arch/x86/hvm/ioreq.c > +++ b/xen/arch/x86/hvm/ioreq.c > @@ -33,6 +33,22 @@ > > #include <public/hvm/ioreq.h> > > +#define SET_IOREQ_SERVER(d, id, s) \ > + (d)->arch.hvm_domain.ioreq_server.server[id] = (s) Are the parentheses around s required? > + > +#define GET_IOREQ_SERVER(d, id) \ > + (((id) < MAX_NR_IOREQ_SERVERS) ? \ > + (d)->arch.hvm_domain.ioreq_server.server[id] : \ > + NULL) > + > +#define FOR_EACH_IOREQ_SERVER(d, id, s) \ > + for ( (id) = 0, (s) = GET_IOREQ_SERVER((d), (id)); \ > + (id) < MAX_NR_IOREQ_SERVERS; \ > + (id)++, (s) = GET_IOREQ_SERVER((d), (id)) ) Same here about the parentheses around s, d and id in the GET_IOREQ_SERVER calls. In fact you could compact the afterthought as: s = GET_IOREQ_SERVER(d, ++(id)) But that's just a nit. > int hvm_create_ioreq_server(struct domain *d, domid_t domid, > @@ -685,52 +674,67 @@ int hvm_create_ioreq_server(struct domain *d, domid_t > domid, > ioservid_t *id) > { > struct hvm_ioreq_server *s; > + unsigned int i; > int rc; > > if ( bufioreq_handling > HVM_IOREQSRV_BUFIOREQ_ATOMIC ) > return -EINVAL; > > - rc = -ENOMEM; > s = xzalloc(struct hvm_ioreq_server); > if ( !s ) > - goto fail1; > + return -ENOMEM; > > domain_pause(d); > spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock); > > - rc = -EEXIST; > - if ( is_default && d->arch.hvm_domain.default_ioreq_server != NULL ) > - goto fail2; > - > - rc = hvm_ioreq_server_init(s, d, domid, is_default, bufioreq_handling, > - next_ioservid(d)); > - if ( rc ) > - goto fail3; > - > - list_add(&s->list_entry, > - &d->arch.hvm_domain.ioreq_server.list); > - > if ( is_default ) > { > - d->arch.hvm_domain.default_ioreq_server = s; > - hvm_ioreq_server_enable(s, true); > + i = DEFAULT_IOSERVID; > + > + rc = -EEXIST; > + if ( GET_IOREQ_SERVER(d, i) ) > + goto fail; > + } > + else > + { > + for ( i = 0; i < MAX_NR_IOREQ_SERVERS; i++ ) > + { > + if ( i != DEFAULT_IOSERVID && > + !GET_IOREQ_SERVER(d, i) ) No need for the newline, the condition fits in a single line. And since you have the macros, this could also be written in terms of FOR_EACH_IOREQ_SERVER. Not really sure it's worth it anyway, you would have to introduce another struct hvm_ioreq_server pointer here. > + break; > + } > + > + rc = -ENOSPC; > + if ( i >= MAX_NR_IOREQ_SERVERS ) > + goto fail; > } > > + SET_IOREQ_SERVER(d, i, s); > + > + rc = hvm_ioreq_server_init(s, d, domid, bufioreq_handling, i); > + if ( rc ) > + goto fail; > + > + if ( IS_DEFAULT(s) ) > + hvm_ioreq_server_enable(s); > + > if ( id ) > - *id = s->id; > + *id = i; > + > + d->arch.hvm_domain.ioreq_server.count++; > > spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock); > domain_unpause(d); > > return 0; > > - fail3: > - fail2: > + fail: > + SET_IOREQ_SERVER(d, i, NULL); > + > spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock); > domain_unpause(d); > > xfree(s); > - fail1: > return rc; > } > > @@ -741,35 +745,30 @@ int hvm_destroy_ioreq_server(struct domain *d, > ioservid_t id) > > spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock); > > - rc = -ENOENT; > - list_for_each_entry ( s, > - &d->arch.hvm_domain.ioreq_server.list, > - list_entry ) > - { > - if ( s == d->arch.hvm_domain.default_ioreq_server ) > - continue; > + s = GET_IOREQ_SERVER(d, id); > > - if ( s->id != id ) > - continue; > - > - domain_pause(d); > + rc = -ENOENT; > + if ( !s || IS_DEFAULT(s) ) > + goto out; In the !s case ENOENT is fine, in the default case however EPERM might be better? Or EOPNOTSUPP? Anyway, just a nit. > > - p2m_set_ioreq_server(d, 0, s); > + domain_pause(d); > > - hvm_ioreq_server_disable(s, false); > + p2m_set_ioreq_server(d, 0, s); > > - list_del(&s->list_entry); > + hvm_ioreq_server_disable(s); > + hvm_ioreq_server_deinit(s); > > - hvm_ioreq_server_deinit(s, false); > + domain_unpause(d); > > - domain_unpause(d); > + ASSERT(d->arch.hvm_domain.ioreq_server.count); > + --d->arch.hvm_domain.ioreq_server.count; > > - xfree(s); > + SET_IOREQ_SERVER(d, id, NULL); > + xfree(s); > > - rc = 0; > - break; > - } > + rc = 0; > > + out: > spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock); > > return rc; > @@ -785,29 +784,23 @@ int hvm_get_ioreq_server_info(struct domain *d, > ioservid_t id, > > spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock); > > - rc = -ENOENT; > - list_for_each_entry ( s, > - &d->arch.hvm_domain.ioreq_server.list, > - list_entry ) > - { > - if ( s == d->arch.hvm_domain.default_ioreq_server ) > - continue; > - > - if ( s->id != id ) > - continue; > + s = GET_IOREQ_SERVER(d, id); > > - *ioreq_gfn = s->ioreq.gfn; > + rc = -ENOENT; > + if ( !s || IS_DEFAULT(s) ) See above the comment about the ENOENT/EOPNOTSUPP thing. Thanks, Roger. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |