From patchwork Wed Oct 26 15:26:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Pisati X-Patchwork-Id: 121930 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id D15931007D2 for ; Thu, 27 Oct 2011 02:26:30 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1RJ5My-0001Oy-RY; Wed, 26 Oct 2011 15:26:20 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1RJ5Mr-0001Kl-4c for kernel-team@lists.ubuntu.com; Wed, 26 Oct 2011 15:26:13 +0000 Received: from dynamic-adsl-94-36-81-3.clienti.tiscali.it ([94.36.81.3] helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1RJ5Mq-00042z-T7 for kernel-team@lists.ubuntu.com; Wed, 26 Oct 2011 15:26:13 +0000 From: Paolo Pisati To: kernel-team@lists.ubuntu.com Subject: [PATCH 4/6] epoll: don't use current in irq context Date: Wed, 26 Oct 2011 17:26:03 +0200 Message-Id: <1319642765-9333-5-git-send-email-paolo.pisati@canonical.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1319642765-9333-1-git-send-email-paolo.pisati@canonical.com> References: <1319642765-9333-1-git-send-email-paolo.pisati@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com From: Tony Battersby ep_call_nested() (formerly ep_poll_safewake()) uses "current" (without dereferencing it) to detect callback recursion, but it may be called from irq context where the use of current is generally discouraged. It would be better to use get_cpu() and put_cpu() to detect the callback recursion. Signed-off-by: Tony Battersby Acked-by: Davide Libenzi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds (cherry picked from commit abff55cee1039b5a3b96f7a5eb6e65b9f247a274) Signed-off-by: Paolo Pisati --- fs/eventpoll.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index fe950e6..863620e 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -113,8 +113,8 @@ struct epoll_filefd { */ struct nested_call_node { struct list_head llink; - struct task_struct *task; void *cookie; + int cpu; }; /* @@ -334,7 +334,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests, { int error, call_nests = 0; unsigned long flags; - struct task_struct *this_task = current; + int this_cpu = get_cpu(); struct list_head *lsthead = &ncalls->tasks_call_list; struct nested_call_node *tncur; struct nested_call_node tnode; @@ -347,20 +347,19 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests, * very much limited. */ list_for_each_entry(tncur, lsthead, llink) { - if (tncur->task == this_task && + if (tncur->cpu == this_cpu && (tncur->cookie == cookie || ++call_nests > max_nests)) { /* * Ops ... loop detected or maximum nest level reached. * We abort this wake by breaking the cycle itself. */ - spin_unlock_irqrestore(&ncalls->lock, flags); - - return -1; + error = -1; + goto out_unlock; } } /* Add the current task and cookie to the list */ - tnode.task = this_task; + tnode.cpu = this_cpu; tnode.cookie = cookie; list_add(&tnode.llink, lsthead); @@ -372,8 +371,10 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests, /* Remove the current task from the list */ spin_lock_irqsave(&ncalls->lock, flags); list_del(&tnode.llink); + out_unlock: spin_unlock_irqrestore(&ncalls->lock, flags); + put_cpu(); return error; }