Ta-Da! Finally the commit you've been waiting for. This is yet one of the bottlenecks. Each API has to go through the list of network objects to find the correct one to work on. But currently it's done in suboptimal way: every single network object is locked, and then compared. If found, it's returned, if not it's unlocked and the loop continues with its sibling. This is not optimal as locking every network object can make us waiting for other APIs finish their job. Therefore we serialize here effectively. Fortunately, with previous patches we are sure that network definition will not change as we traverse the list. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/conf/network_conf.c | 26 ++++++++++++++++++++------ src/conf/network_conf.h | 1 + 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 007cebb..a1bdaf5 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -162,13 +162,20 @@ virNetworkObjFindByUUIDLocked(virNetworkObjListPtr nets, size_t i; for (i = 0; i < nets->count; i++) { - virObjectLock(nets->objs[i]); if (!memcmp(nets->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) { ret = nets->objs[i]; virObjectRef(ret); break; } - virObjectUnlock(nets->objs[i]); + } + + if (ret) { + virObjectLock(ret); + if (ret->removing) { + virObjectUnref(ret); + virObjectUnlock(ret); + ret = NULL; + } } return ret; @@ -193,13 +200,20 @@ virNetworkObjFindByNameLocked(virNetworkObjListPtr nets, size_t i; for (i = 0; i < nets->count; i++) { - virObjectLock(nets->objs[i]); if (STREQ(nets->objs[i]->def->name, name)) { ret = nets->objs[i]; virObjectRef(ret); break; } - virObjectUnlock(nets->objs[i]); + } + + if (ret) { + virObjectLock(ret); + if (ret->removing) { + virObjectUnref(ret); + virObjectUnlock(ret); + ret = NULL; + } } return ret; @@ -675,17 +689,17 @@ void virNetworkRemoveInactive(virNetworkObjListPtr nets, { size_t i; + net->removing = true; virObjectUnlock(net); virObjectLock(nets); + virObjectLock(net); for (i = 0; i < nets->count; i++) { - virObjectLock(nets->objs[i]); if (nets->objs[i] == net) { VIR_DELETE_ELEMENT(nets->objs, i, nets->count); virObjectUnlock(net); virObjectUnref(net); break; } - virObjectUnlock(nets->objs[i]); } virObjectUnlock(nets); } diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index c2e1885..29d13c9 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -273,6 +273,7 @@ struct _virNetworkObj { unsigned long long floor_sum; /* sum of all 'floor'-s of attached NICs */ unsigned int taint; + bool removing; }; virNetworkObjPtr virNetworkObjNew(void); -- 2.0.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list