From: Roger Pau Monne Date: Fri, 23 Feb 2018 13:32:23 +0000 (+0000) Subject: xen: introduce rangeset_consume_ranges X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=7727197839b9ced828cd5f05d62781831c9bfed3;p=people%2Froyger%2Fxen.git xen: introduce rangeset_consume_ranges This function allows to iterate over a rangeset while removing the processed regions. This will be used in order to split processing of large memory areas when mapping them into the guest p2m. Signed-off-by: Roger Pau Monné Reviewed-by: Wei Liu --- Cc: George Dunlap Cc: Ian Jackson Cc: Jan Beulich Cc: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Tim Deegan Cc: Wei Liu --- Changes since v6: - Expand commit message. - Add a comment to describe the expected function behavior. - Fix indentation. Changes since v5: - New in this version. --- diff --git a/xen/common/rangeset.c b/xen/common/rangeset.c index ade34f6a50..bb68ce62e4 100644 --- a/xen/common/rangeset.c +++ b/xen/common/rangeset.c @@ -350,6 +350,34 @@ int rangeset_claim_range(struct rangeset *r, unsigned long size, return 0; } +int rangeset_consume_ranges(struct rangeset *r, + int (*cb)(unsigned long s, unsigned long e, void *, + unsigned long *c), + void *ctxt) +{ + int rc = 0; + + write_lock(&r->lock); + while ( !rangeset_is_empty(r) ) + { + unsigned long consumed = 0; + struct range *x = first_range(r); + + rc = cb(x->s, x->e, ctxt, &consumed); + + ASSERT(consumed <= x->e - x->s + 1); + x->s += consumed; + if ( x->s > x->e ) + destroy_range(r, x); + + if ( rc ) + break; + } + write_unlock(&r->lock); + + return rc; +} + int rangeset_add_singleton( struct rangeset *r, unsigned long s) { diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h index 1f83b1f44b..583b72bb0c 100644 --- a/xen/include/xen/rangeset.h +++ b/xen/include/xen/rangeset.h @@ -70,6 +70,16 @@ int rangeset_report_ranges( struct rangeset *r, unsigned long s, unsigned long e, int (*cb)(unsigned long s, unsigned long e, void *), void *ctxt); +/* + * Note that the consume function can return an error value apart from + * -ERESTART, and that no cleanup is performed (ie: the user should call + * rangeset_destroy if needed). + */ +int rangeset_consume_ranges(struct rangeset *r, + int (*cb)(unsigned long s, unsigned long e, + void *, unsigned long *c), + void *ctxt); + /* Add/remove/query a single number. */ int __must_check rangeset_add_singleton( struct rangeset *r, unsigned long s);