From patchwork Wed Jun 3 14:43:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 6538841 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6E418C0020 for ; Wed, 3 Jun 2015 14:44:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E0732065D for ; Wed, 3 Jun 2015 14:44:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 719112065E for ; Wed, 3 Jun 2015 14:44:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755942AbbFCOoY (ORCPT ); Wed, 3 Jun 2015 10:44:24 -0400 Received: from mail-wg0-f49.google.com ([74.125.82.49]:36621 "EHLO mail-wg0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754935AbbFCOoM (ORCPT ); Wed, 3 Jun 2015 10:44:12 -0400 Received: by wgbgq6 with SMTP id gq6so11192402wgb.3 for ; Wed, 03 Jun 2015 07:44:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eEChthV94LHKvVX3M0xxz3Xj+tD7UiGZHnM5GX3PHS0=; b=g/4neevMyhbuNQquATgJG/ZA8mA1FaDN7nl6aCgmTW3Z5BCJxBMby2tkO23XahS2ER KZj+sugKxrThydZfeacFuA8LcJ45Ln8ePcYPgGP471oBJ/sFxmPlxCUUatYmSQVQTOVT B9O4Haq7rJn5uW1UO0JyCHpUYWhX27HYDaenqWXFF3GoDQS1Qz7LpUpjMyMijjNZE3Pb xXDPHVQTdk7ABkdENhqPw6az06xIyo36wKHcoAOVXM0ia305tsCX83LvygL+tj5fZWYH zX65dNe9NomsAHnsz14Gl4iwMMcWjQCGAf4/3CD5J/H5jhMafg/9SRhNpzB2S5ylwFsU C6DA== X-Gm-Message-State: ALoCoQnZZwPUyOz+hqRF5s/JoTiJUUUPBCQk+aRWkiGPurknFGJJjEN9d209Ema0S1w78WLzkMY4 X-Received: by 10.180.92.70 with SMTP id ck6mr23794713wib.91.1433342650659; Wed, 03 Jun 2015 07:44:10 -0700 (PDT) Received: from tlielax.poochiereds.net ([2606:a000:1105:8e:3a60:77ff:fe93:a95d]) by mx.google.com with ESMTPSA id ch2sm1992397wib.18.2015.06.03.07.44.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Jun 2015 07:44:09 -0700 (PDT) From: Jeff Layton X-Google-Original-From: Jeff Layton To: Trond Myklebust Cc: linux-nfs@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Mel Gorman , Jerome Marchand , Chuck Lever Subject: [PATCH v2 2/5] sunrpc: make xprt->swapper an atomic_t Date: Wed, 3 Jun 2015 10:43:49 -0400 Message-Id: <1433342632-16173-3-git-send-email-jeff.layton@primarydata.com> X-Mailer: git-send-email 2.4.2 In-Reply-To: <1433342632-16173-1-git-send-email-jeff.layton@primarydata.com> References: <1433342632-16173-1-git-send-email-jeff.layton@primarydata.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Split xs_swapper into enable/disable functions and eliminate the "enable" flag. Currently, it's racy if you have multiple swapon/swapoff operations running in parallel over the same xprt. Also fix it so that we only set it to a memalloc socket on a 0->1 transition and only clear it on a 1->0 transition. Cc: Mel Gorman Signed-off-by: Jeff Layton --- include/linux/sunrpc/xprt.h | 5 +++-- net/sunrpc/clnt.c | 4 ++-- net/sunrpc/xprtsock.c | 38 +++++++++++++++++++++++++------------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 8b93ef53df3c..26b1624128ec 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -180,7 +180,7 @@ struct rpc_xprt { atomic_t num_reqs; /* total slots */ unsigned long state; /* transport state */ unsigned char resvport : 1; /* use a reserved port */ - unsigned int swapper; /* we're swapping over this + atomic_t swapper; /* we're swapping over this transport */ unsigned int bind_index; /* bind function index */ @@ -345,7 +345,8 @@ void xprt_release_rqst_cong(struct rpc_task *task); void xprt_disconnect_done(struct rpc_xprt *xprt); void xprt_force_disconnect(struct rpc_xprt *xprt); void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie); -int xs_swapper(struct rpc_xprt *xprt, int enable); +int xs_swapper_enable(struct rpc_xprt *xprt); +void xs_swapper_disable(struct rpc_xprt *xprt); bool xprt_lock_connect(struct rpc_xprt *, struct rpc_task *, void *); void xprt_unlock_connect(struct rpc_xprt *, void *); diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 383cb778179f..804a75e71e84 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2492,7 +2492,7 @@ retry: goto retry; } - ret = xs_swapper(xprt, 1); + ret = xs_swapper_enable(xprt); xprt_put(xprt); } return ret; @@ -2519,7 +2519,7 @@ retry: goto retry; } - xs_swapper(xprt, 0); + xs_swapper_disable(xprt); xprt_put(xprt); } } diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index b29703996028..a2861bbfd319 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1966,31 +1966,43 @@ static void xs_set_memalloc(struct rpc_xprt *xprt) struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); - if (xprt->swapper) + if (atomic_read(&xprt->swapper)) sk_set_memalloc(transport->inet); } /** - * xs_swapper - Tag this transport as being used for swap. + * xs_swapper_enable - Tag this transport as being used for swap. * @xprt: transport to tag - * @enable: enable/disable * + * Take a reference to this transport on behalf of the rpc_clnt, and + * optionally mark it for swapping if it wasn't already. */ -int xs_swapper(struct rpc_xprt *xprt, int enable) +int +xs_swapper_enable(struct rpc_xprt *xprt) { struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); - int err = 0; - if (enable) { - xprt->swapper++; - xs_set_memalloc(xprt); - } else if (xprt->swapper) { - xprt->swapper--; - sk_clear_memalloc(transport->inet); - } + if (atomic_inc_return(&xprt->swapper) == 1) + sk_set_memalloc(transport->inet); + return 0; +} - return err; +/** + * xs_swapper_disable - Untag this transport as being used for swap. + * @xprt: transport to tag + * + * Drop a "swapper" reference to this xprt on behalf of the rpc_clnt. If the + * swapper refcount goes to 0, untag the socket as a memalloc socket. + */ +void +xs_swapper_disable(struct rpc_xprt *xprt) +{ + struct sock_xprt *transport = container_of(xprt, struct sock_xprt, + xprt); + + if (atomic_dec_and_test(&xprt->swapper)) + sk_clear_memalloc(transport->inet); } #else static void xs_set_memalloc(struct rpc_xprt *xprt)