From nobody Mon Feb 9 19:06:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1674035751; cv=none; d=zohomail.com; s=zohoarc; b=Kf+LpfcCFaJjxozVjaeocYvjMooGHELj0X+phsZNOuQwxpjZD3sQmYYPkDzCG/6W4Rx7AO/WVF3k6UKRjeHSJLBj6lSF7Ub5nxbyCl3Otg/sI0j4PN/4YjNxoyKLw4En9GgBpCMgyS6SiTrfahC/6nG4WWVjMmeGZ7jA3Kqo+dY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674035751; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9xr3XDR0lnAcLZVwe7SbDNgcb70DTfqFJY2CcMlXwhM=; b=LOfaN8XEsYbI58p9hTiIg0I4ec5SUJ1g24gTsJuwzpxjhfNvVmAtjallRzjJ1VlmN6mao50THw6i2GrsC9cX82BuDEmqPx5duzmGRcfuqwLXWlKedfwDUceYjEFpwXIQTj+ZgzIxUXKIwP5WeFmY0UvJNkhbC5kVA2/M2RaukQg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1674035751445967.6053363600001; Wed, 18 Jan 2023 01:55:51 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.480371.744806 (Exim 4.92) (envelope-from ) id 1pI5A8-0007sk-46; Wed, 18 Jan 2023 09:55:20 +0000 Received: by outflank-mailman (output) from mailman id 480371.744806; Wed, 18 Jan 2023 09:55:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pI5A7-0007p7-HW; Wed, 18 Jan 2023 09:55:19 +0000 Received: by outflank-mailman (input) for mailman id 480371; Wed, 18 Jan 2023 09:55:17 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pI56U-0001BV-Hs for xen-devel@lists.xenproject.org; Wed, 18 Jan 2023 09:51:34 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 7bb8bd32-9715-11ed-b8d1-410ff93cb8f0; Wed, 18 Jan 2023 10:50:04 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 42FE020D6A; Wed, 18 Jan 2023 09:51:32 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 111C5139D2; Wed, 18 Jan 2023 09:51:32 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id Um3AAiTBx2PtQwAAMHmgww (envelope-from ); Wed, 18 Jan 2023 09:51:32 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 7bb8bd32-9715-11ed-b8d1-410ff93cb8f0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1674035492; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9xr3XDR0lnAcLZVwe7SbDNgcb70DTfqFJY2CcMlXwhM=; b=nGd7aTH7CkPAeVkvRL8PVcp0qRzINcHi8y3X0BL1fF4/E455VF1rqpsgjTg4vFU/Tgn3mU TrraDprG29Pf39R9TsK4xqtyUxxcZ6Mh7oC+1nMqb76SuCoZIGYUOpp+PJt0How0OjAcW3 zK9cu2Tb8lsMob+SF7rFx6aTtMXLJDE= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD , Julien Grall Subject: [PATCH v4 13/17] tools/xenstore: switch hashtable to use the talloc framework Date: Wed, 18 Jan 2023 10:50:12 +0100 Message-Id: <20230118095016.13091-14-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230118095016.13091-1-jgross@suse.com> References: <20230118095016.13091-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1674035753134100003 Content-Type: text/plain; charset="utf-8" Instead of using malloc() and friends, let the hashtable implementation use the talloc framework. This is more consistent with the rest of xenstored and it allows to track memory usage via "xenstore-control memreport". Signed-off-by: Juergen Gross Reviewed-by: Julien Grall --- V3: - make key and value children of element (if flagged) --- tools/xenstore/hashtable.c | 98 +++++++++++-------------------- tools/xenstore/hashtable.h | 3 +- tools/xenstore/xenstored_core.c | 5 +- tools/xenstore/xenstored_domain.c | 2 +- 4 files changed, 38 insertions(+), 70 deletions(-) diff --git a/tools/xenstore/hashtable.c b/tools/xenstore/hashtable.c index ddca1591a2..30eb9f21d2 100644 --- a/tools/xenstore/hashtable.c +++ b/tools/xenstore/hashtable.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include "talloc.h" =20 struct entry { @@ -50,7 +52,7 @@ indexFor(unsigned int tablelength, unsigned int hashvalue= ) { =20 /*************************************************************************= ****/ struct hashtable * -create_hashtable(unsigned int minsize, +create_hashtable(const void *ctx, unsigned int minsize, unsigned int (*hashf) (void*), int (*eqf) (void*,void*), unsigned int flags) @@ -66,10 +68,10 @@ create_hashtable(unsigned int minsize, if (primes[pindex] > minsize) { size =3D primes[pindex]; break; } } =20 - h =3D (struct hashtable *)calloc(1, sizeof(struct hashtable)); + h =3D talloc_zero(ctx, struct hashtable); if (NULL =3D=3D h) goto err0; - h->table =3D (struct entry **)calloc(size, sizeof(struct entry *)); + h->table =3D talloc_zero_array(h, struct entry *, size); if (NULL =3D=3D h->table) goto err1; =20 @@ -83,7 +85,7 @@ create_hashtable(unsigned int minsize, return h; =20 err1: - free(h); + talloc_free(h); err0: return NULL; } @@ -115,47 +117,32 @@ hashtable_expand(struct hashtable *h) if (h->primeindex =3D=3D (prime_table_length - 1)) return 0; newsize =3D primes[++(h->primeindex)]; =20 - newtable =3D (struct entry **)calloc(newsize, sizeof(struct entry*)); - if (NULL !=3D newtable) + newtable =3D talloc_realloc(h, h->table, struct entry *, newsize); + if (!newtable) { - /* This algorithm is not 'stable'. ie. it reverses the list - * when it transfers entries between the tables */ - for (i =3D 0; i < h->tablelength; i++) { - while (NULL !=3D (e =3D h->table[i])) { - h->table[i] =3D e->next; - index =3D indexFor(newsize,e->h); + h->primeindex--; + return 0; + } + + h->table =3D newtable; + memset(newtable + h->tablelength, 0, + (newsize - h->tablelength) * sizeof(*newtable)); + for (i =3D 0; i < h->tablelength; i++) { + for (pE =3D &(newtable[i]), e =3D *pE; e !=3D NULL; e =3D *pE) { + index =3D indexFor(newsize, e->h); + if (index =3D=3D i) + { + pE =3D &(e->next); + } + else + { + *pE =3D e->next; e->next =3D newtable[index]; newtable[index] =3D e; } } - free(h->table); - h->table =3D newtable; - } - /* Plan B: realloc instead */ - else=20 - { - newtable =3D (struct entry **) - realloc(h->table, newsize * sizeof(struct entry *)); - if (NULL =3D=3D newtable) { (h->primeindex)--; return 0; } - h->table =3D newtable; - memset(newtable + h->tablelength, 0, - (newsize - h->tablelength) * sizeof(*newtable)); - for (i =3D 0; i < h->tablelength; i++) { - for (pE =3D &(newtable[i]), e =3D *pE; e !=3D NULL; e =3D *pE)= { - index =3D indexFor(newsize,e->h); - if (index =3D=3D i) - { - pE =3D &(e->next); - } - else - { - *pE =3D e->next; - e->next =3D newtable[index]; - newtable[index] =3D e; - } - } - } } + h->tablelength =3D newsize; h->loadlimit =3D (unsigned int) (((uint64_t)newsize * max_load_factor) / 100); @@ -184,12 +171,16 @@ hashtable_insert(struct hashtable *h, void *k, void *= v) * element may be ok. Next time we insert, we'll try expanding aga= in.*/ hashtable_expand(h); } - e =3D (struct entry *)calloc(1, sizeof(struct entry)); + e =3D talloc_zero(h, struct entry); if (NULL =3D=3D e) { --(h->entrycount); return 0; } /*oom*/ e->h =3D hash(h,k); index =3D indexFor(h->tablelength,e->h); e->k =3D k; + if (h->flags & HASHTABLE_FREE_KEY) + talloc_steal(e, k); e->v =3D v; + if (h->flags & HASHTABLE_FREE_VALUE) + talloc_steal(e, v); e->next =3D h->table[index]; h->table[index] =3D e; return -1; @@ -235,11 +226,7 @@ hashtable_remove(struct hashtable *h, void *k) { *pE =3D e->next; h->entrycount--; - if (h->flags & HASHTABLE_FREE_KEY) - free(e->k); - if (h->flags & HASHTABLE_FREE_VALUE) - free(e->v); - free(e); + talloc_free(e); return; } pE =3D &(e->next); @@ -278,26 +265,7 @@ hashtable_iterate(struct hashtable *h, void hashtable_destroy(struct hashtable *h) { - unsigned int i; - struct entry *e, *f; - struct entry **table =3D h->table; - - for (i =3D 0; i < h->tablelength; i++) - { - e =3D table[i]; - while (NULL !=3D e) - { - f =3D e; - e =3D e->next; - if (h->flags & HASHTABLE_FREE_KEY) - free(f->k); - if (h->flags & HASHTABLE_FREE_VALUE) - free(f->v); - free(f); - } - } - free(h->table); - free(h); + talloc_free(h); } =20 /* diff --git a/tools/xenstore/hashtable.h b/tools/xenstore/hashtable.h index 780ad3c8f7..4e2823134e 100644 --- a/tools/xenstore/hashtable.h +++ b/tools/xenstore/hashtable.h @@ -9,6 +9,7 @@ struct hashtable; * create_hashtable =20 * @name create_hashtable + * @param ctx talloc context to use for allocations * @param minsize minimum initial size of hashtable * @param hashfunction function for hashing keys * @param key_eq_fn function for determining key equality @@ -22,7 +23,7 @@ struct hashtable; #define HASHTABLE_FREE_KEY (1U << 1) =20 struct hashtable * -create_hashtable(unsigned int minsize, +create_hashtable(const void *ctx, unsigned int minsize, unsigned int (*hashfunction) (void*), int (*key_eq_fn) (void*,void*), unsigned int flags diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_cor= e.c index 9cfde76898..17e678256e 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -2405,11 +2405,10 @@ static int keys_equal_fn(void *key1, void *key2) =20 int remember_string(struct hashtable *hash, const char *str) { - char *k =3D malloc(strlen(str) + 1); + char *k =3D talloc_strdup(NULL, str); =20 if (!k) return 0; - strcpy(k, str); return hashtable_insert(hash, k, (void *)1); } =20 @@ -2504,7 +2503,7 @@ void check_store(void) }; =20 /* Don't free values (they are all void *1) */ - reachable =3D create_hashtable(16, hash_from_key_fn, keys_equal_fn, + reachable =3D create_hashtable(NULL, 16, hash_from_key_fn, keys_equal_fn, HASHTABLE_FREE_KEY); if (!reachable) { log("check_store: ENOMEM"); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_d= omain.c index 391395060e..4f4c0a727c 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -931,7 +931,7 @@ void domain_init(int evtfd) int rc; =20 /* Start with a random rather low domain count for the hashtable. */ - domhash =3D create_hashtable(8, domhash_fn, domeq_fn, 0); + domhash =3D create_hashtable(NULL, 8, domhash_fn, domeq_fn, 0); if (!domhash) barf_perror("Failed to allocate domain hashtable"); =20 --=20 2.35.3