Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp729469ybi; Fri, 21 Jun 2019 07:13:23 -0700 (PDT) X-Google-Smtp-Source: APXvYqzOIs19txh2olqb8Fz3iKAxpfrWlKuNn+HjeTDxo+AGfnXca60o/xEkfKnXyzJaFrpCb0F5 X-Received: by 2002:a17:902:be0a:: with SMTP id r10mr8379437pls.51.1561126402968; Fri, 21 Jun 2019 07:13:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561126402; cv=none; d=google.com; s=arc-20160816; b=r01KmdpG2E47JVM8cSRBlUpQ+W3+NsJvRSTCIEvumnswp3aLfUzvsamEHujBaRGRyj ZVjerdKfPVSEC00H2Bkb9FnyZRmEPNnSIwD4twS4fhCnvFIF/7GWUqMpynPat53jdVhx vn6p5okBvBij+aJlk/Zfu9lEdAe/XPPCT+ec1ChxfiuNAugk0JZghE89GToJkCybyBu6 xp7Gu4t/mlfAjcRkZECfG9jfetElfh4A5ciQo6+imgVKcsxeBK80+5Y+zcMOjCyQVK8q gmmdMYJ4YviU1hz9DFre6caoGdF/R9c56AscT267VoAdtcLnPHxas6rAxH6a8hWMVO5T Sz4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:in-reply-to :mime-version:user-agent:date:message-id:from:cc:references:to :subject; bh=zOtvcEJ1H4eNbu1B2QAx1qgH4LhzVz9yco7djUzPy94=; b=oG4I8gLwzx3ttwPq+wCZdf7iVK+SAt95e3AgJCpm+P4lJ0C1Usgmhb6tiaC1a1ZeUL +uQTaMsFL7yOOg9CU1quHepfF7yD1ZqBTLx9oZ/x5aAgLiIJmuM8u5cRYtETErF9WHwa jME81s2nhJhf1HAO97xKJGhD3/RNtVQvIbr4bJWv/E+ppVXvgLyuAhhuFu8ypuaC2zdt R90/oB/o8lRZ82zRsVC7fb21Ce9P9Ijp3lXnu0vQxAMpcx4d3kC57L0CpOg97H9KTea5 YFumuxtUO1iw8l8lvTwn8CWkaA+iktr2kr0oaw2yHesoG9do7lkS9jXWIx1OrvopVvOy Nchg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l2si2858825pju.5.2019.06.21.07.13.07; Fri, 21 Jun 2019 07:13:22 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726274AbfFUOMm (ORCPT + 99 others); Fri, 21 Jun 2019 10:12:42 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:36208 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725985AbfFUOMk (ORCPT ); Fri, 21 Jun 2019 10:12:40 -0400 Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 0630A528127AE37879EE; Fri, 21 Jun 2019 22:12:36 +0800 (CST) Received: from [127.0.0.1] (10.202.227.238) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.439.0; Fri, 21 Jun 2019 22:12:29 +0800 Subject: Re: [PATCH 1/5] lib: logic_pio: Fix RCU usage To: Bjorn Helgaas References: <1561026716-140537-1-git-send-email-john.garry@huawei.com> <1561026716-140537-2-git-send-email-john.garry@huawei.com> <20190621134332.GC82584@google.com> CC: , , , , , From: John Garry Message-ID: <885f3c01-82b9-5978-5e7f-1130021bde57@huawei.com> Date: Fri, 21 Jun 2019 15:12:24 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 In-Reply-To: <20190621134332.GC82584@google.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [10.202.227.238] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 21/06/2019 14:43, Bjorn Helgaas wrote: > On Thu, Jun 20, 2019 at 06:31:52PM +0800, John Garry wrote: Hi Bjorn, >> The traversing of io_range_list with list_for_each_entry_rcu() >> is not properly protected by rcu_read_lock(), so add it. >> Functions rcu_read_lock() and rcu_read_unlock() mark the critical section scope where the list is protected for the reader, it cannot be "reclaimed". Any updater - in this case, the logical PIO registration or unregistration functions - cannot update the list until the reader exits this critical section. >> In addition, the list traversing used in logic_pio_register_range() >> does not need to use the rcu variant. We don't need rcu variant as we're already using the mutex to guarantee mutual exclusion from mutating the list. > > Not being an RCU expert myself, a few words here about why one path > needs protection but the other doesn't would be helpful. This > basically restates what the patch *does*, which is obvious from the > diff, but not *why*. OK, I can add what I mentioned above. Thanks again, John > >> Fixes: 031e3601869c ("lib: Add generic PIO mapping method") >> Signed-off-by: John Garry >> --- >> lib/logic_pio.c | 49 +++++++++++++++++++++++++++++++++++-------------- >> 1 file changed, 35 insertions(+), 14 deletions(-) >> >> diff --git a/lib/logic_pio.c b/lib/logic_pio.c >> index feea48fd1a0d..761296376fbc 100644 >> --- a/lib/logic_pio.c >> +++ b/lib/logic_pio.c >> @@ -46,7 +46,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range) >> end = new_range->hw_start + new_range->size; >> >> mutex_lock(&io_range_mutex); >> - list_for_each_entry_rcu(range, &io_range_list, list) { >> + list_for_each_entry(range, &io_range_list, list) { >> if (range->fwnode == new_range->fwnode) { >> /* range already there */ >> goto end_register; >> @@ -108,26 +108,38 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range) >> */ >> struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode) >> { >> - struct logic_pio_hwaddr *range; >> + struct logic_pio_hwaddr *range, *found_range = NULL; >> >> + rcu_read_lock(); >> list_for_each_entry_rcu(range, &io_range_list, list) { >> - if (range->fwnode == fwnode) >> - return range; >> + if (range->fwnode == fwnode) { >> + found_range = range; >> + break; >> + } >> } >> - return NULL; >> + rcu_read_unlock(); >> + >> + return found_range; >> } >> >> /* Return a registered range given an input PIO token */ >> static struct logic_pio_hwaddr *find_io_range(unsigned long pio) >> { >> - struct logic_pio_hwaddr *range; >> + struct logic_pio_hwaddr *range, *found_range = NULL; >> >> + rcu_read_lock(); >> list_for_each_entry_rcu(range, &io_range_list, list) { >> - if (in_range(pio, range->io_start, range->size)) >> - return range; >> + if (in_range(pio, range->io_start, range->size)) { >> + found_range = range; >> + break; >> + } >> } >> - pr_err("PIO entry token %lx invalid\n", pio); >> - return NULL; >> + rcu_read_unlock(); >> + >> + if (!found_range) >> + pr_err("PIO entry token 0x%lx invalid\n", pio); >> + >> + return found_range; >> } >> >> /** >> @@ -180,14 +192,23 @@ unsigned long logic_pio_trans_cpuaddr(resource_size_t addr) >> { >> struct logic_pio_hwaddr *range; >> >> + rcu_read_lock(); >> list_for_each_entry_rcu(range, &io_range_list, list) { >> if (range->flags != LOGIC_PIO_CPU_MMIO) >> continue; >> - if (in_range(addr, range->hw_start, range->size)) >> - return addr - range->hw_start + range->io_start; >> + if (in_range(addr, range->hw_start, range->size)) { >> + unsigned long cpuaddr; >> + >> + cpuaddr = addr - range->hw_start + range->io_start; >> + >> + rcu_read_unlock(); >> + return cpuaddr; >> + } >> } >> - pr_err("addr %llx not registered in io_range_list\n", >> - (unsigned long long) addr); >> + rcu_read_unlock(); >> + >> + pr_err("addr %pa not registered in io_range_list\n", &addr); >> + >> return ~0UL; >> } >> >> -- >> 2.17.1 >> > > . >