From patchwork Mon Sep 17 13:16:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Derr X-Patchwork-Id: 1467151 Return-Path: X-Original-To: patchwork-v9fs-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by patchwork2.kernel.org (Postfix) with ESMTP id 6F2F2DF2D8 for ; Mon, 17 Sep 2012 13:41:56 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=sfs-ml-3.b.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1TDbZz-0005Eg-0b; Mon, 17 Sep 2012 13:41:39 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1TDbZx-0005EQ-Dp for v9fs-developer@lists.sourceforge.net; Mon, 17 Sep 2012 13:41:37 +0000 X-ACL-Warn: Received: from ecfrec.frec.bull.fr ([129.183.4.8]) by sog-mx-4.v43.ch3.sourceforge.com with esmtp (Exim 4.76) id 1TDbZq-0003Up-BT for v9fs-developer@lists.sourceforge.net; Mon, 17 Sep 2012 13:41:37 +0000 Received: from localhost (localhost [127.0.0.1]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id 2AC8219DD7D; Mon, 17 Sep 2012 15:16:42 +0200 (CEST) Received: from ecfrec.frec.bull.fr ([127.0.0.1]) by localhost (ecfrec.frec.bull.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 02140-01; Mon, 17 Sep 2012 15:16:34 +0200 (CEST) Received: from atlas.frec.bull.fr (atlas.frec.bull.fr [129.183.91.13]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id B9C9F19DD62; Mon, 17 Sep 2012 15:16:33 +0200 (CEST) Received: by atlas.frec.bull.fr (Postfix, from userid 15269) id 8A46337FF9F; Mon, 17 Sep 2012 15:16:33 +0200 (CEST) From: Simon Derr To: v9fs-developer@lists.sourceforge.net Date: Mon, 17 Sep 2012 15:16:28 +0200 Message-Id: <1347887791-13726-2-git-send-email-simon.derr@bull.net> X-Mailer: git-send-email 1.7.2.2 In-Reply-To: <1347887791-13726-1-git-send-email-simon.derr@bull.net> References: <1347887791-13726-1-git-send-email-simon.derr@bull.net> To: v9fs-developer@lists.sourceforge.net X-Virus-Scanned: by amavisd-new at frec.bull.fr X-Spam-Score: -0.5 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain X-Headers-End: 1TDbZq-0003Up-BT Cc: simon.derr@bull.net Subject: [V9fs-developer] [PATCH 1/4] 9P: Fix race in p9_read_work() X-BeenThere: v9fs-developer@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: v9fs-developer-bounces@lists.sourceforge.net Race scenario between p9_read_work() and p9_poll_mux() Data arrive, Rworksched is set, p9_read_work() is called. thread A thread B p9_read_work() . reads data . checks if new data ready. No. . gets preempted . More data arrive, p9_poll_mux() is called. . . . p9_poll_mux() . . if (!test_and_set_bit(Rworksched, . &m->wsched)) { . schedule_work(&m->rq); . } . . -> does not schedule work because . Rworksched is set . . clear_bit(Rworksched, &m->wsched); return; No work has been scheduled, and yet data are waiting. Currently p9_read_work() checks if there is data to read, and if not, it clears Rworksched. I think it should clear Rworksched first, and then check if there is data to read. Signed-off-by: Simon Derr --- net/9p/trans_fd.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 6449bae..15f55b3 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -316,8 +316,7 @@ static void p9_read_work(struct work_struct *work) m->rsize - m->rpos); p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err); if (err == -EAGAIN) { - clear_bit(Rworksched, &m->wsched); - return; + goto end_clear; } if (err <= 0) @@ -379,19 +378,20 @@ static void p9_read_work(struct work_struct *work) m->req = NULL; } +end_clear: + clear_bit(Rworksched, &m->wsched); + if (!list_empty(&m->req_list)) { if (test_and_clear_bit(Rpending, &m->wsched)) n = POLLIN; else n = p9_fd_poll(m->client, NULL); - if (n & POLLIN) { + if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) { p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m); schedule_work(&m->rq); - } else - clear_bit(Rworksched, &m->wsched); - } else - clear_bit(Rworksched, &m->wsched); + } + } return; error: