Received: by 10.223.148.5 with SMTP id 5csp6347008wrq; Wed, 17 Jan 2018 12:31:04 -0800 (PST) X-Google-Smtp-Source: ACJfBospMspkcuPUWAUZQ4l2BZq3dvk2P/KT0IWmqc8SJ2k/EupbWYMdHB5Wh3b0RXgXjBQ7x+JJ X-Received: by 10.98.62.69 with SMTP id l66mr15848517pfa.20.1516221064686; Wed, 17 Jan 2018 12:31:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516221064; cv=none; d=google.com; s=arc-20160816; b=xZqMV2Aw7+HSKqBcjwjjmWYTZ0SjCRm7aUJ8Iqr5Tg4d/a29qK1gnfMS11RfDVklIU XaYea7xFb7zztz3ZWWuRP2ZWRKYJ+J4a8h9CEst2S0fnFbSkq15PN57SaN+oQujvflQk CRxEz8QBGaXJWdmWJPTb+qxUWbrquVaj2/2xbEJfrYeBT3QoOAEVksih11I592fADjNn 15lmcoWtRDd3dFJF7vFP58EwPq6AdI3k16dxkT4es8VhWG+wWYi4vNHnc5UiTe50LPdL 97TChGS/eWduYLx3gDfHTNBlc5kMlrh1XWMK8H6/lS6Sae11LLpSjEWqNYeD7lrPcg4A F90Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=JhuHPFLlYbwqxeR/orJj9pxXezSFdCJ1s1TJfn+xsf8=; b=b2Yp33FepjAXDTSRx6g8qpmZ3XOltoyXiKTkVJZ3Y/snDAPdK4l1n1h0lf+58MP/ng gZ1JM1EVd3XHtF8Y67kWYxUZqy7lWMrMkR7VfCb7OIDQvPHdcg9i+8x9fWYiggO4oQfd X67PJ2v8SrRjf68cB7MP5/gnnCcyKYU7OCx2ZE0kNGGwWbH5vFPBhGysYye3yt1APWd3 l9mcvsG5CFA/d8m4l5atVGWzTiWpEmOtia5+hYtYjTpF0VP1X76lkTYNdhmwLiYXMxZS rFJc/LedNo4gO1tWW0TC7wjCs9bXPU4mQpuIBPkBg+zwRYnN001R94033pNh+8+BZttY ln/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=aPk3c72I; 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 f64si5209015plf.473.2018.01.17.12.30.50; Wed, 17 Jan 2018 12:31:04 -0800 (PST) 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; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=aPk3c72I; 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 S1753686AbeAQU37 (ORCPT + 99 others); Wed, 17 Jan 2018 15:29:59 -0500 Received: from bombadil.infradead.org ([65.50.211.133]:48189 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753992AbeAQUXD (ORCPT ); Wed, 17 Jan 2018 15:23:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=JhuHPFLlYbwqxeR/orJj9pxXezSFdCJ1s1TJfn+xsf8=; b=aPk3c72INSJ7NjNWxHWqgRVeh 3Wlxcq7wjeB8Cldpa56v3z/vNkKvjJR8zaDUT9z+1J6uW71wQl8ZGh5hXvRcwuZZHqbefEQUnSOYp SA2I86vTq1HL655MOlg+FK0YNet9lCvZglrwMR69NyuImyJr/qLTT4oRAdchyj7z+IkKqEKvpcCyX qa8Omda5AZr6DISxjtxgI9HVfSsaJ+4NMdGE0CCsi+qQHF0vK+q/ezsEvkWmegOYE+BRUcvZOsgNz 5ef8tJnvi4ewT6cPN/GL8pKR7RlZLCRxdOR9/Z1GDRoESUO9MML/D+B4D+DvKd7sYSgiWmWtCx/68 xK2fzJ0uA==; Received: from willy by bombadil.infradead.org with local (Exim 4.89 #1 (Red Hat Linux)) id 1ebuEf-0006HQ-Hi; Wed, 17 Jan 2018 20:23:01 +0000 From: Matthew Wilcox To: linux-kernel@vger.kernel.org Cc: Matthew Wilcox , linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-nilfs@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-xfs@vger.kernel.org, linux-usb@vger.kernel.org, Bjorn Andersson , Stefano Stabellini , iommu@lists.linux-foundation.org, linux-remoteproc@vger.kernel.org, linux-s390@vger.kernel.org, intel-gfx@lists.freedesktop.org, cgroups@vger.kernel.org, linux-sh@vger.kernel.org, David Howells Subject: [PATCH v6 86/99] btrfs: Convert reada_zones to XArray Date: Wed, 17 Jan 2018 12:21:50 -0800 Message-Id: <20180117202203.19756-87-willy@infradead.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180117202203.19756-1-willy@infradead.org> References: <20180117202203.19756-1-willy@infradead.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Matthew Wilcox The use of the reada_lock means we have to use the xa_reserve() API. If we can avoid using reada_lock to protect this xarray, we can drop the use of that function. Signed-off-by: Matthew Wilcox --- fs/btrfs/reada.c | 54 +++++++++++++++++++----------------------------------- fs/btrfs/volumes.c | 2 +- fs/btrfs/volumes.h | 2 +- 3 files changed, 21 insertions(+), 37 deletions(-) diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index ab852b8e3e37..ef8e84ff2012 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c @@ -239,17 +239,16 @@ static struct reada_zone *reada_find_zone(struct btrfs_device *dev, u64 logical, { struct btrfs_fs_info *fs_info = dev->fs_info; int ret; - struct reada_zone *zone; + struct reada_zone *curr, *zone; struct btrfs_block_group_cache *cache = NULL; u64 start; u64 end; + unsigned long index = logical >> PAGE_SHIFT; int i; - zone = NULL; spin_lock(&fs_info->reada_lock); - ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, - logical >> PAGE_SHIFT, 1); - if (ret == 1 && logical >= zone->start && logical <= zone->end) { + zone = xa_find(&dev->reada_zones, &index, ULONG_MAX, XA_PRESENT); + if (zone && logical >= zone->start && logical <= zone->end) { kref_get(&zone->refcnt); spin_unlock(&fs_info->reada_lock); return zone; @@ -269,7 +268,8 @@ static struct reada_zone *reada_find_zone(struct btrfs_device *dev, u64 logical, if (!zone) return NULL; - ret = radix_tree_preload(GFP_KERNEL); + ret = xa_reserve(&dev->reada_zones, + (unsigned long)(end >> PAGE_SHIFT), GFP_KERNEL); if (ret) { kfree(zone); return NULL; @@ -290,21 +290,18 @@ static struct reada_zone *reada_find_zone(struct btrfs_device *dev, u64 logical, zone->ndevs = bbio->num_stripes; spin_lock(&fs_info->reada_lock); - ret = radix_tree_insert(&dev->reada_zones, + curr = xa_cmpxchg(&dev->reada_zones, (unsigned long)(zone->end >> PAGE_SHIFT), - zone); - - if (ret == -EEXIST) { + NULL, zone, GFP_NOWAIT | __GFP_NOWARN); + if (curr) { kfree(zone); - ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, - logical >> PAGE_SHIFT, 1); - if (ret == 1 && logical >= zone->start && logical <= zone->end) + zone = curr; + if (logical >= zone->start && logical <= zone->end) kref_get(&zone->refcnt); else zone = NULL; } spin_unlock(&fs_info->reada_lock); - radix_tree_preload_end(); return zone; } @@ -537,9 +534,7 @@ static void reada_zone_release(struct kref *kref) { struct reada_zone *zone = container_of(kref, struct reada_zone, refcnt); - radix_tree_delete(&zone->device->reada_zones, - zone->end >> PAGE_SHIFT); - + xa_erase(&zone->device->reada_zones, zone->end >> PAGE_SHIFT); kfree(zone); } @@ -592,7 +587,7 @@ static void reada_peer_zones_set_lock(struct reada_zone *zone, int lock) for (i = 0; i < zone->ndevs; ++i) { struct reada_zone *peer; - peer = radix_tree_lookup(&zone->devs[i]->reada_zones, index); + peer = xa_load(&zone->devs[i]->reada_zones, index); if (peer && peer->device != zone->device) peer->locked = lock; } @@ -603,12 +598,11 @@ static void reada_peer_zones_set_lock(struct reada_zone *zone, int lock) */ static int reada_pick_zone(struct btrfs_device *dev) { - struct reada_zone *top_zone = NULL; + struct reada_zone *zone, *top_zone = NULL; struct reada_zone *top_locked_zone = NULL; u64 top_elems = 0; u64 top_locked_elems = 0; unsigned long index = 0; - int ret; if (dev->reada_curr_zone) { reada_peer_zones_set_lock(dev->reada_curr_zone, 0); @@ -616,14 +610,7 @@ static int reada_pick_zone(struct btrfs_device *dev) dev->reada_curr_zone = NULL; } /* pick the zone with the most elements */ - while (1) { - struct reada_zone *zone; - - ret = radix_tree_gang_lookup(&dev->reada_zones, - (void **)&zone, index, 1); - if (ret == 0) - break; - index = (zone->end >> PAGE_SHIFT) + 1; + xa_for_each(&dev->reada_zones, zone, index, ULONG_MAX, XA_PRESENT) { if (zone->locked) { if (zone->elems > top_locked_elems) { top_locked_elems = zone->elems; @@ -819,15 +806,13 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all) spin_lock(&fs_info->reada_lock); list_for_each_entry(device, &fs_devices->devices, dev_list) { + struct reada_zone *zone; + btrfs_debug(fs_info, "dev %lld has %d in flight", device->devid, atomic_read(&device->reada_in_flight)); index = 0; - while (1) { - struct reada_zone *zone; - ret = radix_tree_gang_lookup(&device->reada_zones, - (void **)&zone, index, 1); - if (ret == 0) - break; + xa_for_each(&dev->reada_zones, zone, index, ULONG_MAX, + XA_PRESENT) { pr_debug(" zone %llu-%llu elems %llu locked %d devs", zone->start, zone->end, zone->elems, zone->locked); @@ -839,7 +824,6 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all) pr_cont(" curr off %llu", device->reada_next - zone->start); pr_cont("\n"); - index = (zone->end >> PAGE_SHIFT) + 1; } cnt = 0; index = 0; diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index cba286183ff9..8e683799b436 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -247,7 +247,7 @@ static struct btrfs_device *__alloc_device(void) atomic_set(&dev->reada_in_flight, 0); atomic_set(&dev->dev_stats_ccnt, 0); btrfs_device_data_ordered_init(dev); - INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_DIRECT_RECLAIM); + xa_init(&dev->reada_zones); INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_DIRECT_RECLAIM); return dev; diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 335fd1590458..aeabe03d3e44 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -139,7 +139,7 @@ struct btrfs_device { atomic_t reada_in_flight; u64 reada_next; struct reada_zone *reada_curr_zone; - struct radix_tree_root reada_zones; + struct xarray reada_zones; struct radix_tree_root reada_extents; /* disk I/O failure stats. For detailed description refer to -- 2.15.1