From patchwork Thu Sep 8 05:54:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steffen Klassert X-Patchwork-Id: 667302 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3sV9yN5Tmlz9sXR for ; Thu, 8 Sep 2016 16:53:00 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932463AbcIHGwt (ORCPT ); Thu, 8 Sep 2016 02:52:49 -0400 Received: from a.mx.secunet.com ([62.96.220.36]:36353 "EHLO a.mx.secunet.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754211AbcIHGvZ (ORCPT ); Thu, 8 Sep 2016 02:51:25 -0400 Received: from localhost (alg1 [127.0.0.1]) by a.mx.secunet.com (Postfix) with ESMTP id EEC301A0785; Thu, 8 Sep 2016 07:55:00 +0200 (CEST) X-Virus-Scanned: by secunet Received: from a.mx.secunet.com ([127.0.0.1]) by localhost (a.mx.secunet.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id aPaiiFm4eSVC; Thu, 8 Sep 2016 07:55:00 +0200 (CEST) Received: from mail-essen-01.secunet.de (unknown [10.53.40.204]) by a.mx.secunet.com (Postfix) with ESMTP id 390231A0774; Thu, 8 Sep 2016 07:54:54 +0200 (CEST) Received: from gauss.dd.secunet.de (10.182.7.102) by mail-essen-01.secunet.de (10.53.40.204) with Microsoft SMTP Server id 14.3.301.0; Thu, 8 Sep 2016 07:54:59 +0200 Received: by gauss.dd.secunet.de (Postfix, from userid 1000) id 70CA45C0D35; Thu, 8 Sep 2016 07:54:59 +0200 (CEST) From: Steffen Klassert To: David Miller CC: Herbert Xu , Steffen Klassert , Subject: [PATCH 13/17] xfrm: policy: only use rcu in xfrm_sk_policy_lookup Date: Thu, 8 Sep 2016 07:54:48 +0200 Message-ID: <1473314092-11319-14-git-send-email-steffen.klassert@secunet.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1473314092-11319-1-git-send-email-steffen.klassert@secunet.com> References: <1473314092-11319-1-git-send-email-steffen.klassert@secunet.com> MIME-Version: 1.0 X-Originating-IP: [10.182.7.102] X-G-Data-MailSecurity-for-Exchange-SpamLevel: 0 X-G-Data-MailSecurity-for-Exchange-SpamFilter: 0; 1; str=0001.0A0C0205.57D0FD34.0028,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0 X-G-Data-MailSecurity-for-Exchange-State: 0 X-G-Data-MailSecurity-for-Exchange-Error: 0 X-G-Data-MailSecurity-for-Exchange-Sender: 32 X-G-Data-MailSecurity-for-Exchange-Server: d65e63f7-5c15-413f-8f63-c0d707471c93 X-EXCLAIMER-MD-CONFIG: 2c86f778-e09b-4440-8b15-867914633a10 X-G-Data-MailSecurity-for-Exchange-Guid: FD5F2C1E-4F66-45A9-8371-EDECBDDB5650 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Florian Westphal Don't acquire the readlock anymore and rely on rcu alone. In case writer on other CPU changed policy at the wrong moment (after we obtained sk policy pointer but before we could obtain the reference) just repeat the lookup. Signed-off-by: Florian Westphal Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_policy.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9302647..3d27b9a 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1249,10 +1249,9 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, const struct flowi *fl) { struct xfrm_policy *pol; - struct net *net = sock_net(sk); rcu_read_lock(); - read_lock_bh(&net->xfrm.xfrm_policy_lock); + again: pol = rcu_dereference(sk->sk_policy[dir]); if (pol != NULL) { bool match = xfrm_selector_match(&pol->selector, fl, @@ -1267,8 +1266,8 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, err = security_xfrm_policy_lookup(pol->security, fl->flowi_secid, policy_to_flow_dir(dir)); - if (!err) - xfrm_pol_hold(pol); + if (!err && !xfrm_pol_hold_rcu(pol)) + goto again; else if (err == -ESRCH) pol = NULL; else @@ -1277,7 +1276,6 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, pol = NULL; } out: - read_unlock_bh(&net->xfrm.xfrm_policy_lock); rcu_read_unlock(); return pol; }