From patchwork Fri Jul 1 13:34:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Valerio X-Patchwork-Id: 1651202 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fZr0Mf+c; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LZGQt6bxNz9s09 for ; Fri, 1 Jul 2022 23:35:02 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id D2B88846C5; Fri, 1 Jul 2022 13:35:00 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org D2B88846C5 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fZr0Mf+c X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id IocdAZkHdf6v; Fri, 1 Jul 2022 13:34:59 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id BA9ED846D4; Fri, 1 Jul 2022 13:34:58 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org BA9ED846D4 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8E28DC0035; Fri, 1 Jul 2022 13:34:58 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4AE33C002D for ; Fri, 1 Jul 2022 13:34:57 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 3324B61351 for ; Fri, 1 Jul 2022 13:34:57 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 3324B61351 Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fZr0Mf+c X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Yr-wNIxc1DtH for ; Fri, 1 Jul 2022 13:34:56 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 1F99E613D8 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 1F99E613D8 for ; Fri, 1 Jul 2022 13:34:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1656682495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iyjX1zla/MAKp4qeqrM9ZdmRrINc/MouYuroqpWHHmI=; b=fZr0Mf+cANRQTk4ybI+1ZzuPukZq5L31jYoQHHDDEdrulE7OPCy8oPBzROhbBXX/ssvZy8 Dqfn7h/kkXOutZtimnMpmDMiJdIWDzNk2oW9Y2GQj2LgFl4fs90EcQnDssGGn9N4PxgGoa EDBxKl4gLiJiPiMhZ53PMPsoGKQ0FEo= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-265-8_jjkP0mOzGuOgmmAGuJDw-1; Fri, 01 Jul 2022 09:34:54 -0400 X-MC-Unique: 8_jjkP0mOzGuOgmmAGuJDw-1 Received: by mail-wm1-f70.google.com with SMTP id p6-20020a05600c358600b003a0483b3c2eso1425666wmq.3 for ; Fri, 01 Jul 2022 06:34:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=iyjX1zla/MAKp4qeqrM9ZdmRrINc/MouYuroqpWHHmI=; b=1TDhE4hhHelaynss9wFV+BGchGPPxrtby2vopEPs6g/tn6j1D5u6DFTHN5/Vfxv6aF JyxdSUuQQ0p7l4E2KBC22NsAPQ84+JwrcJigWvOHdYUQGdJ8B5BtVl/OWOHgU2//jmk5 1OvEFuNHavAHNXafKG+YWyx79IpGgrwoeOvaBNDDAVaqkkUgFXpBALTePQ8Qz5HPlnNQ FDOTDrKsAuBq0YBCx78Xl+bYQBDL+6MK8Jc08T/2XJDa+n7u8pULkhXczVnqRmU4SIhY eM1MMSZiQbsrNkKMowRPCsCBMppURPxs9X/XhkCHUuXTqMA/OUpnPAMUk2z61GT+ATnk Ywog== X-Gm-Message-State: AJIora+FFszMYTDardupgucAETu1FpEno0wyNGA9X2L/NDSnLXA2P4A6 W72nD20hpaQ0rwqZAmPs4rpAm7iGrFnBSPPx8xO/SB78hlWHJOyuZhZsGONGX0lWZDCgUTbUPiA Gg5fGNPAdrOx1OjStlWa/SCXX0vbN1YF6BGqeLgCSJcNYJ9xeApT/M0ia9bFZF3dG X-Received: by 2002:a05:600c:4f86:b0:3a0:56ad:da10 with SMTP id n6-20020a05600c4f8600b003a056adda10mr15987782wmq.17.1656682492567; Fri, 01 Jul 2022 06:34:52 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uodho+fShCnr1Y9h0stCELYDCCEHZE26p0IzmPRlw/aF7Ew2y85EncIBaX8zp4ks+nqcxFRQ== X-Received: by 2002:a05:600c:4f86:b0:3a0:56ad:da10 with SMTP id n6-20020a05600c4f8600b003a056adda10mr15987745wmq.17.1656682492202; Fri, 01 Jul 2022 06:34:52 -0700 (PDT) Received: from localhost (net-5-95-131-226.cust.vodafonedsl.it. [5.95.131.226]) by smtp.gmail.com with ESMTPSA id ay30-20020a05600c1e1e00b003a033177655sm6810502wmb.29.2022.07.01.06.34.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Jul 2022 06:34:51 -0700 (PDT) From: Paolo Valerio To: dev@openvswitch.org Date: Fri, 01 Jul 2022 15:34:51 +0200 Message-ID: <165668249107.1967719.117828246513672504.stgit@fed.void> In-Reply-To: <165668246947.1967719.4502709837520339365.stgit@fed.void> References: <165668246947.1967719.4502709837520339365.stgit@fed.void> User-Agent: StGit/1.1 MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=pvalerio@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: i.maximets@ovn.org Subject: [ovs-dev] [PATCH v4 1/6] conntrack: Use a cmap to store zone limits X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Gaetan Rivet Change the data structure from hmap to cmap for zone limits. As they are shared amongst multiple conntrack users, multiple readers want to check the current zone limit state before progressing in their processing. Using a CMAP allows doing lookups without taking the global 'ct_lock', thus reducing contention. Signed-off-by: Gaetan Rivet Reviewed-by: Eli Britstein Signed-off-by: Paolo Valerio --- lib/conntrack-private.h | 2 + lib/conntrack.c | 70 ++++++++++++++++++++++++++++++++--------------- lib/conntrack.h | 2 + lib/dpif-netdev.c | 5 ++- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/lib/conntrack-private.h b/lib/conntrack-private.h index dfdf4e676..d9461b811 100644 --- a/lib/conntrack-private.h +++ b/lib/conntrack-private.h @@ -192,7 +192,7 @@ struct conntrack { struct ovs_mutex ct_lock; /* Protects 2 following fields. */ struct cmap conns OVS_GUARDED; struct ovs_list exp_lists[N_CT_TM] OVS_GUARDED; - struct hmap zone_limits OVS_GUARDED; + struct cmap zone_limits OVS_GUARDED; struct hmap timeout_policies OVS_GUARDED; uint32_t hash_basis; /* Salt for hashing a connection key. */ pthread_t clean_thread; /* Periodically cleans up connection tracker. */ diff --git a/lib/conntrack.c b/lib/conntrack.c index faa2d6ab7..6df1142b9 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -81,7 +81,7 @@ enum ct_alg_ctl_type { }; struct zone_limit { - struct hmap_node node; + struct cmap_node node; struct conntrack_zone_limit czl; }; @@ -311,7 +311,7 @@ conntrack_init(void) for (unsigned i = 0; i < ARRAY_SIZE(ct->exp_lists); i++) { ovs_list_init(&ct->exp_lists[i]); } - hmap_init(&ct->zone_limits); + cmap_init(&ct->zone_limits); ct->zone_limit_seq = 0; timeout_policy_init(ct); ovs_mutex_unlock(&ct->ct_lock); @@ -346,12 +346,25 @@ zone_key_hash(int32_t zone, uint32_t basis) } static struct zone_limit * -zone_limit_lookup(struct conntrack *ct, int32_t zone) +zone_limit_lookup_protected(struct conntrack *ct, int32_t zone) OVS_REQUIRES(ct->ct_lock) { uint32_t hash = zone_key_hash(zone, ct->hash_basis); struct zone_limit *zl; - HMAP_FOR_EACH_IN_BUCKET (zl, node, hash, &ct->zone_limits) { + CMAP_FOR_EACH_WITH_HASH_PROTECTED (zl, node, hash, &ct->zone_limits) { + if (zl->czl.zone == zone) { + return zl; + } + } + return NULL; +} + +static struct zone_limit * +zone_limit_lookup(struct conntrack *ct, int32_t zone) +{ + uint32_t hash = zone_key_hash(zone, ct->hash_basis); + struct zone_limit *zl; + CMAP_FOR_EACH_WITH_HASH (zl, node, hash, &ct->zone_limits) { if (zl->czl.zone == zone) { return zl; } @@ -361,7 +374,6 @@ zone_limit_lookup(struct conntrack *ct, int32_t zone) static struct zone_limit * zone_limit_lookup_or_default(struct conntrack *ct, int32_t zone) - OVS_REQUIRES(ct->ct_lock) { struct zone_limit *zl = zone_limit_lookup(ct, zone); return zl ? zl : zone_limit_lookup(ct, DEFAULT_ZONE); @@ -370,13 +382,16 @@ zone_limit_lookup_or_default(struct conntrack *ct, int32_t zone) struct conntrack_zone_limit zone_limit_get(struct conntrack *ct, int32_t zone) { - ovs_mutex_lock(&ct->ct_lock); - struct conntrack_zone_limit czl = {DEFAULT_ZONE, 0, 0, 0}; + struct conntrack_zone_limit czl = { + .zone = DEFAULT_ZONE, + .limit = 0, + .count = ATOMIC_COUNT_INIT(0), + .zone_limit_seq = 0, + }; struct zone_limit *zl = zone_limit_lookup_or_default(ct, zone); if (zl) { czl = zl->czl; } - ovs_mutex_unlock(&ct->ct_lock); return czl; } @@ -384,13 +399,19 @@ static int zone_limit_create(struct conntrack *ct, int32_t zone, uint32_t limit) OVS_REQUIRES(ct->ct_lock) { + struct zone_limit *zl = zone_limit_lookup_protected(ct, zone); + + if (zl) { + return 0; + } + if (zone >= DEFAULT_ZONE && zone <= MAX_ZONE) { - struct zone_limit *zl = xzalloc(sizeof *zl); + zl = xzalloc(sizeof *zl); zl->czl.limit = limit; zl->czl.zone = zone; zl->czl.zone_limit_seq = ct->zone_limit_seq++; uint32_t hash = zone_key_hash(zone, ct->hash_basis); - hmap_insert(&ct->zone_limits, &zl->node, hash); + cmap_insert(&ct->zone_limits, &zl->node, hash); return 0; } else { return EINVAL; @@ -401,13 +422,14 @@ int zone_limit_update(struct conntrack *ct, int32_t zone, uint32_t limit) { int err = 0; - ovs_mutex_lock(&ct->ct_lock); struct zone_limit *zl = zone_limit_lookup(ct, zone); if (zl) { zl->czl.limit = limit; VLOG_INFO("Changed zone limit of %u for zone %d", limit, zone); } else { + ovs_mutex_lock(&ct->ct_lock); err = zone_limit_create(ct, zone, limit); + ovs_mutex_unlock(&ct->ct_lock); if (!err) { VLOG_INFO("Created zone limit of %u for zone %d", limit, zone); } else { @@ -415,7 +437,6 @@ zone_limit_update(struct conntrack *ct, int32_t zone, uint32_t limit) zone); } } - ovs_mutex_unlock(&ct->ct_lock); return err; } @@ -423,23 +444,25 @@ static void zone_limit_clean(struct conntrack *ct, struct zone_limit *zl) OVS_REQUIRES(ct->ct_lock) { - hmap_remove(&ct->zone_limits, &zl->node); - free(zl); + uint32_t hash = zone_key_hash(zl->czl.zone, ct->hash_basis); + cmap_remove(&ct->zone_limits, &zl->node, hash); + ovsrcu_postpone(free, zl); } int zone_limit_delete(struct conntrack *ct, uint16_t zone) { ovs_mutex_lock(&ct->ct_lock); - struct zone_limit *zl = zone_limit_lookup(ct, zone); + struct zone_limit *zl = zone_limit_lookup_protected(ct, zone); if (zl) { zone_limit_clean(ct, zl); + ovs_mutex_unlock(&ct->ct_lock); VLOG_INFO("Deleted zone limit for zone %d", zone); } else { + ovs_mutex_unlock(&ct->ct_lock); VLOG_INFO("Attempted delete of non-existent zone limit: zone %d", zone); } - ovs_mutex_unlock(&ct->ct_lock); return 0; } @@ -456,7 +479,7 @@ conn_clean_cmn(struct conntrack *ct, struct conn *conn) struct zone_limit *zl = zone_limit_lookup(ct, conn->admit_zone); if (zl && zl->czl.zone_limit_seq == conn->zone_limit_seq) { - zl->czl.count--; + atomic_count_dec(&zl->czl.count); } } @@ -510,10 +533,13 @@ conntrack_destroy(struct conntrack *ct) cmap_destroy(&ct->conns); struct zone_limit *zl; - HMAP_FOR_EACH_POP (zl, node, &ct->zone_limits) { - free(zl); + CMAP_FOR_EACH (zl, node, &ct->zone_limits) { + uint32_t hash = zone_key_hash(zl->czl.zone, ct->hash_basis); + + cmap_remove(&ct->zone_limits, &zl->node, hash); + ovsrcu_postpone(free, zl); } - hmap_destroy(&ct->zone_limits); + cmap_destroy(&ct->zone_limits); struct timeout_policy *tp; HMAP_FOR_EACH_POP (tp, node, &ct->timeout_policies) { @@ -991,7 +1017,7 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt, if (commit) { struct zone_limit *zl = zone_limit_lookup_or_default(ct, ctx->key.zone); - if (zl && zl->czl.count >= zl->czl.limit) { + if (zl && atomic_count_get(&zl->czl.count) >= zl->czl.limit) { return nc; } @@ -1064,7 +1090,7 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt, if (zl) { nc->admit_zone = zl->czl.zone; nc->zone_limit_seq = zl->czl.zone_limit_seq; - zl->czl.count++; + atomic_count_inc(&zl->czl.count); } else { nc->admit_zone = INVALID_ZONE; } diff --git a/lib/conntrack.h b/lib/conntrack.h index 9553b188a..58b181834 100644 --- a/lib/conntrack.h +++ b/lib/conntrack.h @@ -108,7 +108,7 @@ struct conntrack_dump { struct conntrack_zone_limit { int32_t zone; uint32_t limit; - uint32_t count; + atomic_count count; uint32_t zone_limit_seq; /* Used to disambiguate zone limit counts. */ }; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index d09138f2c..760cde1a4 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -9263,7 +9263,8 @@ dpif_netdev_ct_get_limits(struct dpif *dpif, czl = zone_limit_get(dp->conntrack, zone_limit->zone); if (czl.zone == zone_limit->zone || czl.zone == DEFAULT_ZONE) { ct_dpif_push_zone_limit(zone_limits_reply, zone_limit->zone, - czl.limit, czl.count); + czl.limit, + atomic_count_get(&czl.count)); } else { return EINVAL; } @@ -9273,7 +9274,7 @@ dpif_netdev_ct_get_limits(struct dpif *dpif, czl = zone_limit_get(dp->conntrack, z); if (czl.zone == z) { ct_dpif_push_zone_limit(zone_limits_reply, z, czl.limit, - czl.count); + atomic_count_get(&czl.count)); } } }