From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756678AbcH2IsC (ORCPT ); Mon, 29 Aug 2016 04:48:02 -0400 Received: from out0-129.mail.aliyun.com ([140.205.0.129]:53673 "EHLO out0-129.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750860AbcH2IsA (ORCPT ); Mon, 29 Aug 2016 04:48:00 -0400 X-Greylist: delayed 316 seconds by postgrey-1.27 at vger.kernel.org; Mon, 29 Aug 2016 04:48:00 EDT X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R201e4;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e02c03299;MF=hillf.zj@alibaba-inc.com;NM=1;PH=DS;RN=2;SR=0;TI=SMTPD_----5DE8N6a_1472460110; Reply-To: "Hillf Danton" From: "Hillf Danton" To: "Oleg Nesterov" Cc: "linux-kernel" References: <00e501d201cf$7bfecd40$73fc67c0$@alibaba-inc.com> In-Reply-To: <00e501d201cf$7bfecd40$73fc67c0$@alibaba-inc.com> Subject: Re: [PATCH 2/2] sched/wait: avoid abort_exclusive_wait() in __wait_on_bit_lock() Date: Mon, 29 Aug 2016 16:41:50 +0800 Message-ID: <00e601d201d1$2fbb1c70$8f315550$@alibaba-inc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQFIbtzyvruWCk+UEbB7hgId2XAAW6FywURw Content-Language: zh-cn Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > > On 08/26, Oleg Nesterov wrote: > > > > We do not need anything tricky to avoid the race, we can just call > > finish_wait() if action() fails. test_and_set_bit() implies mb() so > > the lockless list_empty_careful() case is fine, we can not miss the > > condition if we race with unlock_page(). > > To simplify the review see the code with the patch applied: > > > int __sched > __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, > wait_bit_action_f *action, unsigned mode) > { > int ret = 0; > > for (;;) { > prepare_to_wait_exclusive(wq, &q->wait, mode); > if (test_bit(q->key.bit_nr, q->key.flags)) { > ret = action(&q->key, mode); > /* > * Ensure that clear_bit() + wake_up() right after > * test_and_set_bit() below can't see us; it should > * wake up another exclusive waiter if we fail. > */ > if (ret) > finish_wait(wq, &q->wait); > } > if (!test_and_set_bit(q->key.bit_nr, q->key.flags)) { > if (!ret) > finish_wait(wq, &q->wait); > return 0; > } else if (ret) { > return ret; > } > } > } > Can we fold two bit operations into one? thanks Hillf --- linux-4.7/kernel/sched/wait.c Mon Jul 25 03:23:50 2016 +++ b/kernel/sched/wait.c Mon Aug 29 16:17:01 2016 @@ -425,20 +425,17 @@ int __sched __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, wait_bit_action_f *action, unsigned mode) { - do { - int ret; + int ret = 0; - prepare_to_wait_exclusive(wq, &q->wait, mode); - if (!test_bit(q->key.bit_nr, q->key.flags)) - continue; + prepare_to_wait_exclusive(wq, &q->wait, mode); + do { + if (!test_and_set_bit(q->key.bit_nr, q->key.flags)) + break; ret = action(&q->key, mode); - if (!ret) - continue; - abort_exclusive_wait(wq, &q->wait, mode, &q->key); - return ret; - } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); + } while (!ret); + finish_wait(wq, &q->wait); - return 0; + return ret; } EXPORT_SYMBOL(__wait_on_bit_lock); --