[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 03/13] tools/xenstore: introduce accounting data array for per-domain values
Introduce the scheme of an accounting data array for per-domain accounting data and use it initially for the number of nodes owned by a domain. Make the accounting data type to be unsigned int, as no data is allowed to be negative at any time. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- V3: - remove domid parameter from domain_acc_add_chk() (Julien Grall) - rename domain_acc_add_chk() (Julien Grall) - modify overflow check (Julien Grall) --- tools/xenstore/xenstored_domain.c | 70 ++++++++++++++++++------------- tools/xenstore/xenstored_domain.h | 3 +- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 609a9a13ab..4ff01bac84 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -69,8 +69,8 @@ struct domain /* Has domain been officially introduced? */ bool introduced; - /* number of entry from this domain in the store */ - int nbentry; + /* Accounting data for this domain. */ + unsigned int acc[ACC_N]; /* Amount of memory allocated for this domain. */ int memory; @@ -246,7 +246,7 @@ static int domain_tree_remove_sub(const void *ctx, struct connection *conn, if (keep_orphans) { set_tdb_key(node->name, &key); - domain->nbentry--; + domain_nbentry_dec(NULL, domain->domid); node->perms.p[0].id = priv_domid; node->acc.memory = 0; domain_nbentry_inc(NULL, priv_domid); @@ -270,7 +270,7 @@ static int domain_tree_remove_sub(const void *ctx, struct connection *conn, ret = WALK_TREE_SKIP_CHILDREN; } - return domain->nbentry > 0 ? ret : WALK_TREE_SUCCESS_STOP; + return domain->acc[ACC_NODES] ? ret : WALK_TREE_SUCCESS_STOP; } static void domain_tree_remove(struct domain *domain) @@ -278,7 +278,7 @@ static void domain_tree_remove(struct domain *domain) int ret; struct walk_funcs walkfuncs = { .enter = domain_tree_remove_sub }; - if (domain->nbentry > 0) { + if (domain->acc[ACC_NODES]) { ret = walk_node_tree(domain, NULL, "/", &walkfuncs, domain); if (ret == WALK_TREE_ERROR_STOP) syslog(LOG_ERR, @@ -437,7 +437,7 @@ int domain_get_quota(const void *ctx, struct connection *conn, resp = talloc_asprintf_append(resp, "%-16s: %8d\n", #t, e); \ if (!resp) return ENOMEM - ent(nodes, d->nbentry); + ent(nodes, d->acc[ACC_NODES]); ent(watches, d->nbwatch); ent(transactions, ta); ent(outstanding, d->nboutstanding); @@ -1047,8 +1047,27 @@ int domain_adjust_node_perms(struct node *node) return 0; } -static int domain_nbentry_add(struct connection *conn, unsigned int domid, - int add, bool no_dom_alloc) +static int domain_acc_add_valid(struct domain *d, enum accitem what, int add) +{ + assert(what < ARRAY_SIZE(d->acc)); + + if ((add < 0 && -add > d->acc[what]) || + (INT_MAX - d->acc[what]) < add) { + /* + * In a transaction when a node is being added/removed AND the + * same node has been added/removed outside the transaction in + * parallel, the resulting value will be wrong. This is no + * problem, as the transaction will fail due to the resulting + * conflict. + */ + return (add < 0) ? 0 : INT_MAX; + } + + return d->acc[what] + add; +} + +static int domain_acc_add(struct connection *conn, unsigned int domid, + enum accitem what, int add, bool no_dom_alloc) { struct domain *d; struct list_head *head; @@ -1071,56 +1090,49 @@ static int domain_nbentry_add(struct connection *conn, unsigned int domid, } } - if (conn && conn->transaction) { + if (conn && conn->transaction && what < ACC_TR_N) { head = transaction_get_changed_domains(conn->transaction); - ret = acc_add_changed_dom(conn->transaction, head, ACC_NODES, + ret = acc_add_changed_dom(conn->transaction, head, what, add, domid); if (errno) { fail_transaction(conn->transaction); return -1; } - /* - * In a transaction when a node is being added/removed AND the - * same node has been added/removed outside the transaction in - * parallel, the resulting number of nodes will be wrong. This - * is no problem, as the transaction will fail due to the - * resulting conflict. - * In the node remove case the resulting number can be even - * negative, which should be avoided. - */ - return max(d->nbentry + ret, 0); + return domain_acc_add_valid(d, what, ret); } - d->nbentry += add; + d->acc[what] = domain_acc_add_valid(d, what, add); - return d->nbentry; + return d->acc[what]; } int domain_nbentry_inc(struct connection *conn, unsigned int domid) { - return (domain_nbentry_add(conn, domid, 1, false) < 0) ? errno : 0; + return (domain_acc_add(conn, domid, ACC_NODES, 1, false) < 0) + ? errno : 0; } int domain_nbentry_dec(struct connection *conn, unsigned int domid) { - return (domain_nbentry_add(conn, domid, -1, true) < 0) ? errno : 0; + return (domain_acc_add(conn, domid, ACC_NODES, -1, true) < 0) + ? errno : 0; } int domain_nbentry_fix(unsigned int domid, int num, bool update) { int ret; - ret = domain_nbentry_add(NULL, domid, update ? num : 0, update); + ret = domain_acc_add(NULL, domid, ACC_NODES, update ? num : 0, update); if (ret < 0 || update) return ret; return domid_is_unprivileged(domid) ? ret + num : 0; } -int domain_nbentry(struct connection *conn) +unsigned int domain_nbentry(struct connection *conn) { return domain_is_unprivileged(conn) - ? domain_nbentry_add(conn, conn->id, 0, true) : 0; + ? domain_acc_add(conn, conn->id, ACC_NODES, 0, true) : 0; } static bool domain_chk_quota(struct domain *domain, int mem) @@ -1597,7 +1609,7 @@ static int domain_check_acc_init_sub(const void *k, void *v, void *arg) * If everything is correct incrementing the value for each node will * result in dom->nodes being 0 at the end. */ - dom->nodes = -d->nbentry; + dom->nodes = -d->acc[ACC_NODES]; if (!hashtable_insert(domains, &dom->domid, dom)) { talloc_free(dom); @@ -1652,7 +1664,7 @@ static int domain_check_acc_cb(const void *k, void *v, void *arg) if (!d) return 0; - d->nbentry += dom->nodes; + d->acc[ACC_NODES] += dom->nodes; return 0; } diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 40803574f6..9d05eb01da 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -27,6 +27,7 @@ enum accitem { ACC_NODES, ACC_TR_N, /* Number of elements per transaction. */ + ACC_N = ACC_TR_N, /* Number of elements per domain. */ }; void handle_event(void); @@ -77,7 +78,7 @@ int domain_alloc_permrefs(struct node_perms *perms); int domain_nbentry_inc(struct connection *conn, unsigned int domid); int domain_nbentry_dec(struct connection *conn, unsigned int domid); int domain_nbentry_fix(unsigned int domid, int num, bool update); -int domain_nbentry(struct connection *conn); +unsigned int domain_nbentry(struct connection *conn); int domain_memory_add(unsigned int domid, int mem, bool no_quota_check); /* -- 2.35.3
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |