From patchwork Thu May 11 18:28:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Maloy X-Patchwork-Id: 761281 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 3wP1np6tlQz9s86 for ; Fri, 12 May 2017 04:28:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933979AbdEKS21 (ORCPT ); Thu, 11 May 2017 14:28:27 -0400 Received: from sesbmg22.ericsson.net ([193.180.251.48]:53814 "EHLO sesbmg22.ericsson.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933972AbdEKS20 (ORCPT ); Thu, 11 May 2017 14:28:26 -0400 X-AuditID: c1b4fb30-285ff7000000015f-78-5914ad4687b6 Received: from ESESSHC011.ericsson.se (Unknown_Domain [153.88.183.51]) by sesbmg22.ericsson.net (Symantec Mail Security) with SMTP id 8D.8B.00351.64DA4195; Thu, 11 May 2017 20:28:24 +0200 (CEST) Received: from tipsy.lab.linux.ericsson.se (10.35.28.120) by ESESSHC011.ericsson.se (153.88.183.51) with Microsoft SMTP Server (TLS) id 14.3.339.0; Thu, 11 May 2017 20:28:22 +0200 From: Jon Maloy To: , CC: , , Subject: [PATCH net 1/1] tipc: make macro tipc_wait_for_cond() smp safe Date: Thu, 11 May 2017 20:28:15 +0200 Message-ID: <1494527295-20646-1-git-send-email-jon.maloy@ericsson.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-Originating-IP: [10.35.28.120] X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprPLMWRmVeSWpSXmKPExsUyM2K7sa7HWpFIg58TjSzmnG9hsTi2QMxi y/ksi8fXrzM7sHhsWXmTyWP3gs9MHp83yXms37KVKYAlissmJTUnsyy1SN8ugStjyn+ngrVi FfcurGBrYPzM38XIySEhYCLxsL2dFcQWEjjCKLHoi3cXIxeQvZ1R4ubqf2AJNgENiZfTOhhB bBEBY4lXKzuZQGxmgQKJpxMhaoQF3CUWHZjBDGKzCKhK/O86AFTDwcEr4CbRckAIYpecxPnj P8FKeAUEJU7OfMICMUZC4uCLF8wQNyhLzP0wjQmiXkHi28xupgmMfLOQtMxC0rKAkWkVo2hx anFSbrqRkV5qUWZycXF+nl5easkmRmCwHdzy22AH48vnjocYBTgYlXh4FywTiRRiTSwrrsw9 xCjBwawkwntlCVCINyWxsiq1KD++qDQntfgQozQHi5I4r+O+CxFCAumJJanZqakFqUUwWSYO TqkGxuLSsJSFdfkFU/Mzzy+97Za3VPr+H+/uqpmO1/Z4C3NsZBSQnGWZvLvgcsDOYp3TGX3f rBzSlr7/GrHi1fT1RR8DgsQsvnMeKKjreRvaXn4g5CCfRNCdaJVTP1LeLa/7bfx6i1XA5GMN FzcITzVm2OlzpLAu58GmZt+5VpyfMq/INXCvElO0VWIpzkg01GIuKk4EAFN4VwIyAgAA Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The macro tipc_wait_for_cond() is embedding the macro sk_wait_event() to fulfil its task. The latter, in turn, is evaluating the stated condition outside the socket lock context. This is problematic if the condition is accessing non-trivial data structures which may be altered by incoming interrupts, as is the case with the cong_links() linked list, used by socket to keep track of the current set of congested links. We sometimes see crashes when this list is accessed by a condition function at the same time as a SOCK_WAKEUP interrupt is removing an element from the list. We fix this by expanding selected parts of sk_wait_event() into the outer macro, while ensuring that all evaluations of a given condition are performed under socket lock protection. Fixes: commit 365ad353c256 ("tipc: reduce risk of user starvation during link congestion") Reviewed-by: Parthasarathy Bhuvaragan Signed-off-by: Jon Maloy --- net/tipc/socket.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 0d4f2f4..1b92b72 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -362,25 +362,25 @@ static int tipc_sk_sock_err(struct socket *sock, long *timeout) return 0; } -#define tipc_wait_for_cond(sock_, timeout_, condition_) \ -({ \ - int rc_ = 0; \ - int done_ = 0; \ - \ - while (!(condition_) && !done_) { \ - struct sock *sk_ = sock->sk; \ - DEFINE_WAIT_FUNC(wait_, woken_wake_function); \ - \ - rc_ = tipc_sk_sock_err(sock_, timeout_); \ - if (rc_) \ - break; \ - prepare_to_wait(sk_sleep(sk_), &wait_, \ - TASK_INTERRUPTIBLE); \ - done_ = sk_wait_event(sk_, timeout_, \ - (condition_), &wait_); \ - remove_wait_queue(sk_sleep(sk_), &wait_); \ - } \ - rc_; \ +#define tipc_wait_for_cond(sock_, timeo_, condition_) \ +({ \ + struct sock *sk_; \ + int rc_; \ + \ + while ((rc_ = !(condition_))) { \ + DEFINE_WAIT_FUNC(wait_, woken_wake_function); \ + sk_ = (sock_)->sk; \ + rc_ = tipc_sk_sock_err((sock_), timeo_); \ + if (rc_) \ + break; \ + prepare_to_wait(sk_sleep(sk_), &wait_, TASK_INTERRUPTIBLE); \ + release_sock(sk_); \ + *(timeo_) = wait_woken(&wait_, TASK_INTERRUPTIBLE, *(timeo_)); \ + sched_annotate_sleep(); \ + lock_sock(sk_); \ + remove_wait_queue(sk_sleep(sk_), &wait_); \ + } \ + rc_; \ }) /**