From nobody Thu May 15 19:24:17 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523397960898.2567336400474; Wed, 23 Aug 2017 14:23:17 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 47F0413A9F; Wed, 23 Aug 2017 21:23:16 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2110361F4C; Wed, 23 Aug 2017 21:23:16 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id DE7463FACD; Wed, 23 Aug 2017 21:23:15 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLNEuo024087 for ; Wed, 23 Aug 2017 17:23:14 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8D2FB80DAF; Wed, 23 Aug 2017 21:23:14 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7965E66D39 for ; Wed, 23 Aug 2017 21:23:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 47F0413A9F Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:03 -0400 Message-Id: <20170823212211.4693-8-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 07/15] nodedev: Use virObjectLookupHash X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 23 Aug 2017 21:23:16 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Use the virObjectLookupHash in _virNodeDeviceObjList. Convert the code to use the LookupHash object and APIs rather than code within this module that uses virHash* calls. Since the _virNodeDeviceObjList only now contains the @parent object, the virClassNew must be removed from OnceInit because instantiation would fail since the object size would be the same as the parent object size. Usage of HashLookup{Find|Search} APIs returns a locked/reffed object so remove the virObjectLock after FindBy*Locked calls. The only function requiring taking a lock is the Add function since it needs to be synchronized in such a way to avoid multiple threads attempting to add the same named node device at the same time. The NumOfDevicesCallback and GetNamesCallback can use the same callback function with the only difference being the filling in of the @names array from the passed @data structure if it exists. Signed-off-by: John Ferlan --- src/conf/virnodedeviceobj.c | 273 ++++++++++++----------------------------= ---- 1 file changed, 75 insertions(+), 198 deletions(-) diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index b0dcee1..b97518b 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -40,19 +40,12 @@ struct _virNodeDeviceObj { }; =20 struct _virNodeDeviceObjList { - virObjectLockable parent; - - /* name string -> virNodeDeviceObj mapping - * for O(1), lockless lookup-by-name */ - virHashTable *objs; - + virObjectLookupHash parent; }; =20 =20 static virClassPtr virNodeDeviceObjClass; -static virClassPtr virNodeDeviceObjListClass; static void virNodeDeviceObjDispose(void *opaque); -static void virNodeDeviceObjListDispose(void *opaque); =20 static int virNodeDeviceObjOnceInit(void) @@ -63,12 +56,6 @@ virNodeDeviceObjOnceInit(void) virNodeDeviceObjDispose))) return -1; =20 - if (!(virNodeDeviceObjListClass =3D virClassNew(virClassForObjectLocka= ble(), - "virNodeDeviceObjList", - sizeof(virNodeDeviceObjL= ist), - virNodeDeviceObjListDisp= ose))) - return -1; - return 0; } =20 @@ -229,17 +216,7 @@ virNodeDeviceObjListSearch(virNodeDeviceObjListPtr dev= s, virHashSearcher callback, const void *data) { - virNodeDeviceObjPtr obj; - - virObjectLock(devs); - obj =3D virHashSearch(devs->objs, callback, data, NULL); - virObjectRef(obj); - virObjectUnlock(devs); - - if (obj) - virObjectLock(obj); - - return obj; + return virObjectLookupHashSearchName(devs, callback, (void *)data); } =20 =20 @@ -274,7 +251,7 @@ static virNodeDeviceObjPtr virNodeDeviceObjListFindByNameLocked(virNodeDeviceObjListPtr devs, const char *name) { - return virObjectRef(virHashLookup(devs->objs, name)); + return virObjectLookupHashFindLocked(devs, name); } =20 =20 @@ -282,15 +259,7 @@ virNodeDeviceObjPtr virNodeDeviceObjListFindByName(virNodeDeviceObjListPtr devs, const char *name) { - virNodeDeviceObjPtr obj; - - virObjectLock(devs); - obj =3D virNodeDeviceObjListFindByNameLocked(devs, name); - virObjectUnlock(devs); - if (obj) - virObjectLock(obj); - - return obj; + return virObjectLookupHashFind(devs, name); } =20 =20 @@ -445,32 +414,11 @@ virNodeDeviceObjListFindSCSIHostByWWNs(virNodeDeviceO= bjListPtr devs, } =20 =20 -static void -virNodeDeviceObjListDispose(void *obj) -{ - virNodeDeviceObjListPtr devs =3D obj; - - virHashFree(devs->objs); -} - - virNodeDeviceObjListPtr virNodeDeviceObjListNew(void) { - virNodeDeviceObjListPtr devs; - - if (virNodeDeviceObjInitialize() < 0) - return NULL; - - if (!(devs =3D virObjectLockableNew(virNodeDeviceObjListClass))) - return NULL; - - if (!(devs->objs =3D virHashCreate(50, virObjectFreeHashData))) { - virObjectUnref(devs); - return NULL; - } - - return devs; + return virObjectLookupHashNew(virClassForObjectLookupHash(), 50, + VIR_OBJECT_LOOKUP_HASH_NAME); } =20 =20 @@ -486,29 +434,31 @@ virNodeDeviceObjListAssignDef(virNodeDeviceObjListPtr= devs, virNodeDeviceDefPtr def) { virNodeDeviceObjPtr obj; + virNodeDeviceObjPtr ret =3D NULL; =20 - virObjectLock(devs); + virObjectRWLockWrite(devs); =20 if ((obj =3D virNodeDeviceObjListFindByNameLocked(devs, def->name))) { - virObjectLock(obj); virNodeDeviceDefFree(obj->def); obj->def =3D def; } else { if (!(obj =3D virNodeDeviceObjNew())) goto cleanup; =20 - if (virHashAddEntry(devs->objs, def->name, obj) < 0) { - virNodeDeviceObjEndAPI(&obj); + if (virObjectLookupHashAdd(devs, obj, NULL, def->name) < 0) goto cleanup; - } =20 obj->def =3D def; virObjectRef(obj); } =20 + ret =3D obj; + obj =3D NULL; + cleanup: - virObjectUnlock(devs); - return obj; + virNodeDeviceObjEndAPI(&obj); + virObjectRWUnlock(devs); + return ret; } =20 =20 @@ -516,20 +466,11 @@ void virNodeDeviceObjListRemove(virNodeDeviceObjListPtr devs, virNodeDeviceObjPtr obj) { - virNodeDeviceDefPtr def; - if (!obj) return; - def =3D obj->def; =20 - virObjectRef(obj); - virObjectUnlock(obj); - virObjectLock(devs); - virObjectLock(obj); - virHashRemoveEntry(devs->objs, def->name); - virObjectUnlock(obj); - virObjectUnref(obj); - virObjectUnlock(devs); + /* @obj is already locked on entry */ + virObjectLookupHashRemove(devs, obj, NULL, obj->def->name); } =20 =20 @@ -730,29 +671,33 @@ virNodeDeviceCapMatch(virNodeDeviceObjPtr obj, } =20 =20 -struct virNodeDeviceCountData { - virConnectPtr conn; - virNodeDeviceObjListFilter filter; - const char *matchstr; - int count; -}; - static int -virNodeDeviceObjListNumOfDevicesCallback(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) +virNodeDeviceObjListGetHelper(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) { virNodeDeviceObjPtr obj =3D payload; virNodeDeviceDefPtr def; - struct virNodeDeviceCountData *data =3D opaque; + virObjectLookupHashForEachDataPtr data =3D opaque; virNodeDeviceObjListFilter filter =3D data->filter; + char **names =3D (char **)data->elems; + + if (data->error) + return 0; =20 virObjectLock(obj); def =3D obj->def; + if ((!filter || filter(data->conn, def)) && - (!data->matchstr || virNodeDeviceObjHasCap(obj, data->matchstr))) - data->count++; + (!data->matchStr || virNodeDeviceObjHasCap(obj, data->matchStr))) { + if (names && VIR_STRDUP(names[data->nElems], def->name) < 0) { + data->error =3D true; + goto cleanup; + } + data->nElems++; + } =20 + cleanup: virObjectUnlock(obj); return 0; } @@ -764,55 +709,12 @@ virNodeDeviceObjListNumOfDevices(virNodeDeviceObjList= Ptr devs, const char *cap, virNodeDeviceObjListFilter filter) { - struct virNodeDeviceCountData data =3D { - .conn =3D conn, .filter =3D filter, .matchstr =3D cap, .count =3D = 0 }; - - virObjectLock(devs); - virHashForEach(devs->objs, virNodeDeviceObjListNumOfDevicesCallback, &= data); - virObjectUnlock(devs); + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .matchStr = =3D cap, + .nElems =3D 0, .elems =3D NULL, .maxElems =3D -2 }; =20 - return data.count; -} - - -struct virNodeDeviceGetNamesData { - virConnectPtr conn; - virNodeDeviceObjListFilter filter; - const char *matchstr; - int nnames; - char **names; - int maxnames; - bool error; -}; - -static int -virNodeDeviceObjListGetNamesCallback(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) -{ - virNodeDeviceObjPtr obj =3D payload; - virNodeDeviceDefPtr def; - struct virNodeDeviceGetNamesData *data =3D opaque; - virNodeDeviceObjListFilter filter =3D data->filter; - - if (data->error) - return 0; - - virObjectLock(obj); - def =3D obj->def; - - if ((!filter || filter(data->conn, def)) && - (!data->matchstr || virNodeDeviceObjHasCap(obj, data->matchstr))) { - if (VIR_STRDUP(data->names[data->nnames], def->name) < 0) { - data->error =3D true; - goto cleanup; - } - data->nnames++; - } - - cleanup: - virObjectUnlock(obj); - return 0; + return virObjectLookupHashForEachName(devs, virNodeDeviceObjListGetHel= per, + &data); } =20 =20 @@ -824,23 +726,12 @@ virNodeDeviceObjListGetNames(virNodeDeviceObjListPtr = devs, char **const names, int maxnames) { - struct virNodeDeviceGetNamesData data =3D { - .conn =3D conn, .filter =3D filter, .matchstr =3D cap, .names =3D = names, - .nnames =3D 0, .maxnames =3D maxnames, .error =3D false }; + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .matchStr = =3D cap, + .nElems =3D 0, .elems =3D (void **)names, .maxElems =3D maxnames }; =20 - virObjectLock(devs); - virHashForEach(devs->objs, virNodeDeviceObjListGetNamesCallback, &data= ); - virObjectUnlock(devs); - - if (data.error) - goto error; - - return data.nnames; - - error: - while (--data.nnames) - VIR_FREE(data.names[data.nnames]); - return -1; + return virObjectLookupHashForEachName(devs, virNodeDeviceObjListGetHel= per, + &data); } =20 =20 @@ -876,15 +767,6 @@ virNodeDeviceMatch(virNodeDeviceObjPtr obj, #undef MATCH =20 =20 -struct virNodeDeviceObjListExportData { - virConnectPtr conn; - virNodeDeviceObjListFilter filter; - unsigned int flags; - virNodeDevicePtr *devices; - int ndevices; - bool error; -}; - static int virNodeDeviceObjListExportCallback(void *payload, const void *name ATTRIBUTE_UNUSED, @@ -892,8 +774,10 @@ virNodeDeviceObjListExportCallback(void *payload, { virNodeDeviceObjPtr obj =3D payload; virNodeDeviceDefPtr def; - struct virNodeDeviceObjListExportData *data =3D opaque; + virObjectLookupHashForEachDataPtr data =3D opaque; + virNodeDeviceObjListFilter filter =3D data->filter; virNodeDevicePtr device =3D NULL; + virNodeDevicePtr *devices =3D (virNodeDevicePtr *)data->elems; =20 if (data->error) return 0; @@ -901,20 +785,25 @@ virNodeDeviceObjListExportCallback(void *payload, virObjectLock(obj); def =3D obj->def; =20 - if ((!data->filter || data->filter(data->conn, def)) && - virNodeDeviceMatch(obj, data->flags)) { - if (data->devices) { - if (!(device =3D virGetNodeDevice(data->conn, def->name)) || - VIR_STRDUP(device->parent, def->parent) < 0) { - virObjectUnref(device); - data->error =3D true; - goto cleanup; - } - data->devices[data->ndevices] =3D device; - } - data->ndevices++; + if (filter && !filter(data->conn, def)) + goto cleanup; + + if (!virNodeDeviceMatch(obj, data->flags)) + goto cleanup; + + if (!devices) { + data->nElems++; + goto cleanup; } =20 + if (!(device =3D virGetNodeDevice(data->conn, def->name)) || + VIR_STRDUP(device->parent, def->parent) < 0) { + virObjectUnref(device); + data->error =3D true; + goto cleanup; + } + devices[data->nElems++] =3D device; + cleanup: virObjectUnlock(obj); return 0; @@ -928,31 +817,19 @@ virNodeDeviceObjListExport(virConnectPtr conn, virNodeDeviceObjListFilter filter, unsigned int flags) { - struct virNodeDeviceObjListExportData data =3D { - .conn =3D conn, .filter =3D filter, .flags =3D flags, - .devices =3D NULL, .ndevices =3D 0, .error =3D false }; - - virObjectLock(devs); - if (devices && - VIR_ALLOC_N(data.devices, virHashSize(devs->objs) + 1) < 0) { - virObjectUnlock(devs); - return -1; - } - - virHashForEach(devs->objs, virNodeDeviceObjListExportCallback, &data); - virObjectUnlock(devs); + int ret; + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .nElems =3D = 0, + .elems =3D NULL, .maxElems =3D 0, .flags =3D flags }; =20 - if (data.error) - goto cleanup; + if (devices) + data.maxElems =3D -1; =20 - if (data.devices) { - ignore_value(VIR_REALLOC_N(data.devices, data.ndevices + 1)); - *devices =3D data.devices; - } + ret =3D virObjectLookupHashForEachName(devs, virNodeDeviceObjListExpor= tCallback, + &data); =20 - return data.ndevices; + if (devices) + *devices =3D (virNodeDevicePtr *)data.elems; =20 - cleanup: - virObjectListFree(data.devices); - return -1; + return ret; } --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list