Message ID | 20231123024510.2037882-1-xu.xin.sc@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ce62:0:b0:403:3b70:6f57 with SMTP id o2csp182645vqx; Wed, 22 Nov 2023 18:47:54 -0800 (PST) X-Google-Smtp-Source: AGHT+IHcdly0MnmHMBrmU65jItw2RZTo43NkKWcZOEms7CitJdOdljz9pH/bK7LYEmatRYgHFKxu X-Received: by 2002:a9d:7390:0:b0:6d7:fa6b:e777 with SMTP id j16-20020a9d7390000000b006d7fa6be777mr443295otk.2.1700707674678; Wed, 22 Nov 2023 18:47:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700707674; cv=none; d=google.com; s=arc-20160816; b=ZewvOJlaQpwHyj4QyzvLgidaH+or7ti1cKreWEA1q5lTN/Pkhxvg02jPdZZkSTU+7v rFWJ2lV3otA6Mvcl4d2sWVGGYoEIimsnwU1EFj1SLs6owedEAEgTId3XyEYONxP9mKjS ypjtTSPRRrvZl0pwx3utnNccLudMVqhuIdyFuM2H23OKH4yWMVPey5fR/70eQ5hZ4/uR UiObWR0/2MAU5ef08/2svJlFNW/yR/q3fl/J8hmFEgUn5iG6qZNPXC1EW8cSCH+pbBWl Ns8+sVUidSuCu1cgIKty2LvO5QgDFetxeUUGQghiMF/3fZD+F4jzFx5YNxnV/2av90LW YOUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=8BY40MezrcROj3/F+9yGbhrX7rr/7MPMOcTvBUms6oE=; fh=CjmlAyC0dBSMdiNyngPCarN2z+fStAu38zGG8ZkORkc=; b=YNrDJneFaQhrk8HC3gCmfT5kVfBnR+TenSSZmK2wz0bss+Bh5ZJm1ELurzuI4ZDO+4 f1X7SiSvtAqma3lPMcqHFqNCvFLnNfB+FlMDzzxUSZifoxrnRXElclhpLzGBsRUxTXuK loGrPFHCaHb2IuN0I9cLEkJDWG4lH8S4QG/gVjdFlqBlCuZwzZH+8vKpAtGvyqV7vNXQ mN31fsha5inZEkeLyCH/hAS3r5BG3b2STqn99Evto7flrVpqDob5ftXfqkD3PLDgc0QX tVmRANVFBJlxy/eTRa/g58F9wSrJZglXI1coaydVLnp7mZINtumGe7hCxJJzPVwPeulF lFOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=UPslDqhv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from lipwig.vger.email (lipwig.vger.email. [2620:137:e000::3:3]) by mx.google.com with ESMTPS id h13-20020a63530d000000b005c1b2d279f3si384523pgb.342.2023.11.22.18.47.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Nov 2023 18:47:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) client-ip=2620:137:e000::3:3; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=UPslDqhv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id 516C981DDD25; Wed, 22 Nov 2023 18:45:57 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232688AbjKWCp1 (ORCPT <rfc822;ouuuleilei@gmail.com> + 99 others); Wed, 22 Nov 2023 21:45:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229789AbjKWCpY (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 22 Nov 2023 21:45:24 -0500 Received: from mail-oo1-xc42.google.com (mail-oo1-xc42.google.com [IPv6:2607:f8b0:4864:20::c42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8C7E191; Wed, 22 Nov 2023 18:45:30 -0800 (PST) Received: by mail-oo1-xc42.google.com with SMTP id 006d021491bc7-58d205245feso30123eaf.0; Wed, 22 Nov 2023 18:45:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700707530; x=1701312330; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=8BY40MezrcROj3/F+9yGbhrX7rr/7MPMOcTvBUms6oE=; b=UPslDqhvuuPkNgQNfztukeMUU81+GQpeDIoSpOLkOCaRWzSOUxJdrRjzkFTJARjPb2 z9C0AEzX8dnXi4uq5hFVJV8h6W7Uur0gvLgDwXI43SZeonhA2IfW0ja+WlTBdV1FioB1 vP0aKlYRGz9e0y1kEYjfYLz6xXflKuwMkymMu7Jedigc/68MfX/vZZB55EdzrG1GZr2Y WRZefEVr4qaLjok8++4EKwjpi2MggQPBCh3MIMGubhxKL3M/7wo4nXt7aRuvv/uZpgQK JpwAIVc39SigngyQEf4YQvKDKAuSsKokPCX0mc8qI54PRKGHK5XWcs7k5KaYEe/h3is1 Yn4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700707530; x=1701312330; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=8BY40MezrcROj3/F+9yGbhrX7rr/7MPMOcTvBUms6oE=; b=MxRMItVqioJCdrODaw1l3Dm/nzQGdA6pJfe7h2omTOTY39JhSlDyzYI9s3nqLziP9g 5rZHBgT5Cs7bc53jwPhN0akz5DEnXkN1sLdH/0/sYwnZk+oFBQcdv1nn8mbyCGQrvB2i npHkS/ficrvOo07xkYtBgMMDTcdpBRKjoXqJrbdjH3lQX4/T5R/rXCdCYVV82HdwVTTY AUZ1GlppocftIIdFC/6G3CGAgnR66p1xVERZtdgN4OvLr1dhJ5Izz3cOJK18xvQ6IaFB cPeynGIILpasMhik2COIXSOuemkDlF8KcNbzkVemQL/1xrzX+8XUu9VqqNkg3WULpJj3 /2qg== X-Gm-Message-State: AOJu0YxDHeTNygYoAXpzgI4feLmFosiz7nUE0dPzsaSH3vWGKa3Wqu9z nqTY/jyjccgI1OyvArrEbhM8l7Z7O3Zv9g== X-Received: by 2002:a05:6870:f14f:b0:1f4:be52:b129 with SMTP id l15-20020a056870f14f00b001f4be52b129mr5540504oac.56.1700707529929; Wed, 22 Nov 2023 18:45:29 -0800 (PST) Received: from localhost.localdomain ([193.203.214.57]) by smtp.gmail.com with ESMTPSA id l3-20020a62be03000000b006cb7feae74fsm167990pff.164.2023.11.22.18.45.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Nov 2023 18:45:29 -0800 (PST) From: xu.xin.sc@gmail.com To: jmaloy@redhat.com, ying.xue@windriver.com, davem@davemloft.net Cc: netdev@vger.kernel.org, tipc-discussion@lists.sourceforge.net, linux-kernel@vger.kernel.org, xu.xin16@zte.com.cn, xu xin <xu.xin.sc@gmail.com> Subject: [RFC PATCH] net/tipc: reduce tipc_node lock holding time in tipc_rcv Date: Thu, 23 Nov 2023 02:45:10 +0000 Message-Id: <20231123024510.2037882-1-xu.xin.sc@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Wed, 22 Nov 2023 18:45:57 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783321250784105967 X-GMAIL-MSGID: 1783321250784105967 |
Series |
[RFC] net/tipc: reduce tipc_node lock holding time in tipc_rcv
|
|
Commit Message
xu
Nov. 23, 2023, 2:45 a.m. UTC
From: xu xin <xu.xin.sc@gmail.com> Background ========== As we know, for now, TIPC doesn't support RPS balance based on the port of tipc skb destination. The basic reason is the increased contention of node lock when the packets from the same link are distributed to different CPUs for processing, as mentioned in [1]. Questions to talk ================= Does tipc_link_rcv() really need hold the tipc_node's read or write lock? I tried to look through the procudure code of tipc_link_rcv, I didn't find the reason why it needs the lock. If tipc_link_rcv does need it, Can anyone tells me the reason, and if we can reduce it's holding time more. Advantage ========= If tipc_link_rcv does not need the lock, with this patch applied, enabling RPS based destination port (my experimental code) can increase the tipc throughput by approximately 25% (in a 4-core cpu). [1] commit 08bfc9cb76e2 ("flow_dissector: add tipc support") Signed-off-by: xu xin <xu.xin.sc@gmail.com> --- net/tipc/node.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
Comments
> net/tipc/node.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > >diff --git a/net/tipc/node.c b/net/tipc/node.c index 3105abe97bb9..2a036b8a7da3 100644 >--- a/net/tipc/node.c >+++ b/net/tipc/node.c >@@ -2154,14 +2154,15 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) > /* Receive packet directly if conditions permit */ > tipc_node_read_lock(n); > if (likely((n->state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) { >+ tipc_node_read_unlock(n); > spin_lock_bh(&le->lock); > if (le->link) { > rc = tipc_link_rcv(le->link, skb, &xmitq); > skb = NULL; > } > spin_unlock_bh(&le->lock); >- } >- tipc_node_read_unlock(n); >+ } else >+ tipc_node_read_unlock(n); > > /* Check/update node state before receiving */ > if (unlikely(skb)) { >@@ -2169,12 +2170,13 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) > goto out_node_put; > tipc_node_write_lock(n); > if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { >+ tipc_node_write_unlock(n); > if (le->link) { > rc = tipc_link_rcv(le->link, skb, &xmitq); > skb = NULL; > } >- } >- tipc_node_write_unlock(n); >+ } else >+ tipc_node_write_unlock(n); > } > > if (unlikely(rc & TIPC_LINK_UP_EVT)) >-- >2.15.2 > > This patch is wrong. le->link and link status must be protected by node lock. See what happens if tipc_node_timeout() is called, and the link goes down: tipc_node_timeout() tipc_node_link_down() { struct tipc_link *l = le->link; ... if (delete) { kfree(l); le->link = NULL; } ... }
>>diff --git a/net/tipc/node.c b/net/tipc/node.c index 3105abe97bb9..2a036b8a7da3 100644 >>--- a/net/tipc/node.c >>+++ b/net/tipc/node.c >>@@ -2154,14 +2154,15 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) >> /* Receive packet directly if conditions permit */ >> tipc_node_read_lock(n); >> if (likely((n->state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) { >>+ tipc_node_read_unlock(n); >> spin_lock_bh(&le->lock); >> if (le->link) { >> rc = tipc_link_rcv(le->link, skb, &xmitq); >> skb = NULL; >> } >> spin_unlock_bh(&le->lock); >>- } >>- tipc_node_read_unlock(n); >>+ } else >>+ tipc_node_read_unlock(n); >> >> /* Check/update node state before receiving */ >> if (unlikely(skb)) { >>@@ -2169,12 +2170,13 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) >> goto out_node_put; >> tipc_node_write_lock(n); >> if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { >>+ tipc_node_write_unlock(n); >> if (le->link) { >> rc = tipc_link_rcv(le->link, skb, &xmitq); >> skb = NULL; >> } >>- } >>- tipc_node_write_unlock(n); >>+ } else >>+ tipc_node_write_unlock(n); >> } >> >> if (unlikely(rc & TIPC_LINK_UP_EVT)) >>-- >>2.15.2 >> >> >This patch is wrong. le->link and link status must be protected by node lock. See what happens if tipc_node_timeout() is called, and the link goes down: >tipc_node_timeout() > tipc_node_link_down() > { > struct tipc_link *l = le->link; > ... > if (delete) { > kfree(l); > le->link = NULL; > } > ... > } Happy to see your reply. But Why? 'delete' is false from tipc_node_timeout(). Refer to: https://elixir.bootlin.com/linux/v6.7-rc2/source/net/tipc/node.c#L844
>>This patch is wrong. le->link and link status must be protected by node lock. See what happens if tipc_node_timeout() is called, and >the link goes down: >>tipc_node_timeout() >> tipc_node_link_down() >> { >> struct tipc_link *l = le->link; >> ... >> if (delete) { >> kfree(l); >> le->link = NULL; >> } >> ... >> } > >Happy to see your reply. But Why? 'delete' is false from tipc_node_timeout(). Refer to: >https://elixir.bootlin.com/linux/v6.7-rc2/source/net/tipc/node.c#L844 I should have explained it clearly: 1/ link status must be protected. tipc_node_timeout() tipc_node_link_down() { struct tipc_link *l = le->link; ... __tipc_node_link_down(); <-- link status is referred. ... if (delete) { kfree(l); le->link = NULL; } ... } __tipc_node_link_down() { ... if (!l || tipc_link_is_reset(l)) <-- read link status ... tipc_link_reset(l); <--- this function will reset all things related to link. } 2/ le->link must be protected. bearer_disable() { ... tipc_node_delete_links(net, bearer_id); <--- this will delete all links. ... } tipc_node_delete_links() { ... tipc_node_link_down(n, bearer_id, true); ... }
>>>This patch is wrong. le->link and link status must be protected by node lock. See what happens if tipc_node_timeout() is called, and >>the link goes down: >>>tipc_node_timeout() >>> tipc_node_link_down() >>> { >>> struct tipc_link *l = le->link; >>> ... >>> if (delete) { >>> kfree(l); >>> le->link = NULL; >>> } >>> ... >>> } >> >>Happy to see your reply. But Why? 'delete' is false from tipc_node_timeout(). Refer to: >>https://elixir.bootlin.com/linux/v6.7-rc2/source/net/tipc/node.c#L844 >I should have explained it clearly: Thanks. I see, so the root reason for holding node lock before tipc_link_rcv is to protect links from being reset or deleted when tipc_link_rcv(). For further discussion, to balance incoming packets (the same links, different ports) to multi-CPUs, maybe we can try RCU + spinlock here. >1/ link status must be protected. >tipc_node_timeout() > tipc_node_link_down() > { > struct tipc_link *l = le->link; > > ... > __tipc_node_link_down(); <-- link status is referred. > ... > if (delete) { > kfree(l); > le->link = NULL; > } > ... > } > >__tipc_node_link_down() >{ > ... > if (!l || tipc_link_is_reset(l)) <-- read link status > ... > tipc_link_reset(l); <--- this function will reset all things related to link. >} > >2/ le->link must be protected. >bearer_disable() >{ > ... > tipc_node_delete_links(net, bearer_id); <--- this will delete all links. > ... >} > >tipc_node_delete_links() >{ > ... > tipc_node_link_down(n, bearer_id, true); > ... >}
>>Happy to see your reply. But Why? 'delete' is false from tipc_node_timeout(). Refer to: >>https://elixir.bootlin.com/linux/v6.7-rc2/source/net/tipc/node.c#L844 >I should have explained it clearly: >1/ link status must be protected. >tipc_node_timeout() > tipc_node_link_down() > { > struct tipc_link *l = le->link; > > ... > __tipc_node_link_down(); <-- link status is referred. > ... > if (delete) { > kfree(l); > le->link = NULL; > } > ... > } > >__tipc_node_link_down() >{ > ... > if (!l || tipc_link_is_reset(l)) <-- read link status > ... > tipc_link_reset(l); <--- this function will reset all things related to link. >} > >2/ le->link must be protected. >bearer_disable() >{ > ... > tipc_node_delete_links(net, bearer_id); <--- this will delete all links. > ... >} > >tipc_node_delete_links() >{ > ... > tipc_node_link_down(n, bearer_id, true); > ... >} Could we please solve the problem mentioned above by adding spinlock(&le->lock)? For example: (BTW, I have tested it, with this change, enabling RPS based on tipc port can improve 25% of general throughput) diff --git a/net/tipc/node.c b/net/tipc/node.c index 3105abe97bb9..470c272d798e 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -1079,12 +1079,16 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); } else { /* Defuse pending tipc_node_link_up() */ + spin_lock_bh(&le->lock); tipc_link_reset(l); + spin_unlock_bh(&le->lock); tipc_link_fsm_evt(l, LINK_RESET_EVT); } if (delete) { + spin_lock_bh(&le->lock); kfree(l); le->link = NULL; + spin_unlock_bh(&le->lock); n->link_cnt--; } trace_tipc_node_link_down(n, true, "node link down or deleted!"); @@ -2154,14 +2158,15 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) /* Receive packet directly if conditions permit */ tipc_node_read_lock(n); if (likely((n->state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) { + tipc_node_read_unlock(n); spin_lock_bh(&le->lock); if (le->link) { rc = tipc_link_rcv(le->link, skb, &xmitq); skb = NULL; } spin_unlock_bh(&le->lock); - } - tipc_node_read_unlock(n); + } else + tipc_node_read_unlock(n); /* Check/update node state before receiving */ if (unlikely(skb)) { @@ -2169,12 +2174,13 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) goto out_node_put; tipc_node_write_lock(n); if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { + tipc_node_write_unlock(n); if (le->link) { rc = tipc_link_rcv(le->link, skb, &xmitq); skb = NULL; } - } - tipc_node_write_unlock(n); + } else + tipc_node_write_unlock(n); } if (unlikely(rc & TIPC_LINK_UP_EVT))
>Could we please solve the problem mentioned above by adding spinlock(&le->lock)? > No, you cannot do that. As I said before, the link status (including l->state) needs to be protected by node lock. What I showed you were just 2 use cases (link reset/delete). There are more use cases (netlink, transmit path etc) that need proper locks. >For example: > >(BTW, I have tested it, with this change, enabling RPS based on tipc port can improve 25% of general throughput) > >diff --git a/net/tipc/node.c b/net/tipc/node.c index 3105abe97bb9..470c272d798e 100644 >--- a/net/tipc/node.c >+++ b/net/tipc/node.c >@@ -1079,12 +1079,16 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) > __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); > } else { > /* Defuse pending tipc_node_link_up() */ >+ spin_lock_bh(&le->lock); > tipc_link_reset(l); >+ spin_unlock_bh(&le->lock); > tipc_link_fsm_evt(l, LINK_RESET_EVT); > } > if (delete) { >+ spin_lock_bh(&le->lock); > kfree(l); > le->link = NULL; >+ spin_unlock_bh(&le->lock); > n->link_cnt--; > } > trace_tipc_node_link_down(n, true, "node link down or deleted!"); @@ -2154,14 +2158,15 @@ void tipc_rcv(struct net *net, >struct sk_buff *skb, struct tipc_bearer *b) > /* Receive packet directly if conditions permit */ > tipc_node_read_lock(n); > if (likely((n->state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) { >+ tipc_node_read_unlock(n); > spin_lock_bh(&le->lock); > if (le->link) { > rc = tipc_link_rcv(le->link, skb, &xmitq); > skb = NULL; > } > spin_unlock_bh(&le->lock); >- } >- tipc_node_read_unlock(n); >+ } else >+ tipc_node_read_unlock(n); > > /* Check/update node state before receiving */ > if (unlikely(skb)) { >@@ -2169,12 +2174,13 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) > goto out_node_put; > tipc_node_write_lock(n); > if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { >+ tipc_node_write_unlock(n); > if (le->link) { > rc = tipc_link_rcv(le->link, skb, &xmitq); > skb = NULL; > } >- } >- tipc_node_write_unlock(n); >+ } else >+ tipc_node_write_unlock(n); > } > > if (unlikely(rc & TIPC_LINK_UP_EVT))
>>Could we please solve the problem mentioned above by adding spinlock(&le->lock)? >> > >No, you cannot do that. As I said before, the link status (including l->state) needs to be protected by node lock. Why can't use le->lock instead of node's lock to protect it in tipc_link_rcv. >What I showed you were just 2 use cases (link reset/delete). There are more use cases (netlink, transmit path etc) that need proper locks. The same. We can also add spin_lock_bh(&le->lock) to protect the link in other places where it changes the link status in addition to 'reset/delete'. Because using node lock to protect the link in tipc_link_rcv is really wasting CPU performance. > >>For example: >> >>(BTW, I have tested it, with this change, enabling RPS based on tipc port can improve 25% of general throughput) >> >>diff --git a/net/tipc/node.c b/net/tipc/node.c index 3105abe97bb9..470c272d798e 100644 >>--- a/net/tipc/node.c >>+++ b/net/tipc/node.c >>@@ -1079,12 +1079,16 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) >> __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); >> } else { >> /* Defuse pending tipc_node_link_up() */ >>+ spin_lock_bh(&le->lock); >> tipc_link_reset(l); >>+ spin_unlock_bh(&le->lock); >> tipc_link_fsm_evt(l, LINK_RESET_EVT); >> } >> if (delete) { >>+ spin_lock_bh(&le->lock); >> kfree(l); >> le->link = NULL; >>+ spin_unlock_bh(&le->lock); >> n->link_cnt--; >> } >> trace_tipc_node_link_down(n, true, "node link down or deleted!"); @@ -2154,14 +2158,15 @@ void tipc_rcv(struct net *net, >>struct sk_buff *skb, struct tipc_bearer *b) >> /* Receive packet directly if conditions permit */ >> tipc_node_read_lock(n); >> if (likely((n->state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) { >>+ tipc_node_read_unlock(n); >> spin_lock_bh(&le->lock); >> if (le->link) { >> rc = tipc_link_rcv(le->link, skb, &xmitq); >> skb = NULL; >> } >> spin_unlock_bh(&le->lock); >>- } >>- tipc_node_read_unlock(n); >>+ } else >>+ tipc_node_read_unlock(n); >> >> /* Check/update node state before receiving */ >> if (unlikely(skb)) { >>@@ -2169,12 +2174,13 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) >> goto out_node_put; >> tipc_node_write_lock(n); >> if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { >>+ tipc_node_write_unlock(n); >> if (le->link) { >> rc = tipc_link_rcv(le->link, skb, &xmitq); >> skb = NULL; >> } >>- } >>- tipc_node_write_unlock(n); >>+ } else >>+ tipc_node_write_unlock(n); >> } >> >> if (unlikely(rc & TIPC_LINK_UP_EVT))
>Why can't use le->lock instead of node's lock to protect it in tipc_link_rcv. > I have already explained: __tipc_node_link_down() { ... if (!l || tipc_link_is_reset(l)) <-- read link status ... } >>What I showed you were just 2 use cases (link reset/delete). There are more use cases (netlink, transmit path etc) that need proper >locks. > >The same. We can also add spin_lock_bh(&le->lock) to protect the link in other places where it changes the link status in addition to >'reset/delete'. Because using node lock to protect the link in tipc_link_rcv is really wasting CPU performance. > If you want to change current lock policy, you need to submit a complete/correct patch. I will acknowledge this patch if I can see a significant improvement in my test.
diff --git a/net/tipc/node.c b/net/tipc/node.c index 3105abe97bb9..2a036b8a7da3 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -2154,14 +2154,15 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) /* Receive packet directly if conditions permit */ tipc_node_read_lock(n); if (likely((n->state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) { + tipc_node_read_unlock(n); spin_lock_bh(&le->lock); if (le->link) { rc = tipc_link_rcv(le->link, skb, &xmitq); skb = NULL; } spin_unlock_bh(&le->lock); - } - tipc_node_read_unlock(n); + } else + tipc_node_read_unlock(n); /* Check/update node state before receiving */ if (unlikely(skb)) { @@ -2169,12 +2170,13 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) goto out_node_put; tipc_node_write_lock(n); if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) { + tipc_node_write_unlock(n); if (le->link) { rc = tipc_link_rcv(le->link, skb, &xmitq); skb = NULL; } - } - tipc_node_write_unlock(n); + } else + tipc_node_write_unlock(n); } if (unlikely(rc & TIPC_LINK_UP_EVT))