19
19
#include <linux/highmem.h>
20
20
#include <linux/mutex.h>
21
21
#include <linux/pagemap.h>
22
- #include <linux/radix-tree .h>
22
+ #include <linux/xarray .h>
23
23
#include <linux/fs.h>
24
24
#include <linux/slab.h>
25
25
#include <linux/backing-dev.h>
28
28
#include <linux/uaccess.h>
29
29
30
30
/*
31
- * Each block ramdisk device has a radix_tree brd_pages of pages that stores
31
+ * Each block ramdisk device has a xarray brd_pages of pages that stores
32
32
* the pages containing the block device's contents. A brd page's ->index is
33
33
* its offset in PAGE_SIZE units. This is similar to, but in no way connected
34
34
* with, the kernel's pagecache or buffer cache (which sit above our block
@@ -40,11 +40,9 @@ struct brd_device {
40
40
struct list_head brd_list ;
41
41
42
42
/*
43
- * Backing store of pages and lock to protect it. This is the contents
44
- * of the block device.
43
+ * Backing store of pages. This is the contents of the block device.
45
44
*/
46
- spinlock_t brd_lock ;
47
- struct radix_tree_root brd_pages ;
45
+ struct xarray brd_pages ;
48
46
u64 brd_nr_pages ;
49
47
};
50
48
@@ -56,21 +54,8 @@ static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector)
56
54
pgoff_t idx ;
57
55
struct page * page ;
58
56
59
- /*
60
- * The page lifetime is protected by the fact that we have opened the
61
- * device node -- brd pages will never be deleted under us, so we
62
- * don't need any further locking or refcounting.
63
- *
64
- * This is strictly true for the radix-tree nodes as well (ie. we
65
- * don't actually need the rcu_read_lock()), however that is not a
66
- * documented feature of the radix-tree API so it is better to be
67
- * safe here (we don't have total exclusion from radix tree updates
68
- * here, only deletes).
69
- */
70
- rcu_read_lock ();
71
57
idx = sector >> PAGE_SECTORS_SHIFT ; /* sector to page index */
72
- page = radix_tree_lookup (& brd -> brd_pages , idx );
73
- rcu_read_unlock ();
58
+ page = xa_load (& brd -> brd_pages , idx );
74
59
75
60
BUG_ON (page && page -> index != idx );
76
61
@@ -83,7 +68,7 @@ static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector)
83
68
static int brd_insert_page (struct brd_device * brd , sector_t sector , gfp_t gfp )
84
69
{
85
70
pgoff_t idx ;
86
- struct page * page ;
71
+ struct page * page , * cur ;
87
72
int ret = 0 ;
88
73
89
74
page = brd_lookup_page (brd , sector );
@@ -94,71 +79,42 @@ static int brd_insert_page(struct brd_device *brd, sector_t sector, gfp_t gfp)
94
79
if (!page )
95
80
return - ENOMEM ;
96
81
97
- if (radix_tree_maybe_preload (gfp )) {
98
- __free_page (page );
99
- return - ENOMEM ;
100
- }
82
+ xa_lock (& brd -> brd_pages );
101
83
102
- spin_lock (& brd -> brd_lock );
103
84
idx = sector >> PAGE_SECTORS_SHIFT ;
104
85
page -> index = idx ;
105
- if (radix_tree_insert (& brd -> brd_pages , idx , page )) {
86
+
87
+ cur = __xa_cmpxchg (& brd -> brd_pages , idx , NULL , page , gfp );
88
+
89
+ if (unlikely (cur )) {
106
90
__free_page (page );
107
- page = radix_tree_lookup (& brd -> brd_pages , idx );
108
- if (!page )
109
- ret = - ENOMEM ;
110
- else if (page -> index != idx )
91
+ ret = xa_err (cur );
92
+ if (!ret && (cur -> index != idx ))
111
93
ret = - EIO ;
112
94
} else {
113
95
brd -> brd_nr_pages ++ ;
114
96
}
115
- spin_unlock (& brd -> brd_lock );
116
97
117
- radix_tree_preload_end ();
98
+ xa_unlock (& brd -> brd_pages );
99
+
118
100
return ret ;
119
101
}
120
102
121
103
/*
122
- * Free all backing store pages and radix tree . This must only be called when
104
+ * Free all backing store pages and xarray . This must only be called when
123
105
* there are no other users of the device.
124
106
*/
125
- #define FREE_BATCH 16
126
107
static void brd_free_pages (struct brd_device * brd )
127
108
{
128
- unsigned long pos = 0 ;
129
- struct page * pages [FREE_BATCH ];
130
- int nr_pages ;
131
-
132
- do {
133
- int i ;
134
-
135
- nr_pages = radix_tree_gang_lookup (& brd -> brd_pages ,
136
- (void * * )pages , pos , FREE_BATCH );
137
-
138
- for (i = 0 ; i < nr_pages ; i ++ ) {
139
- void * ret ;
140
-
141
- BUG_ON (pages [i ]-> index < pos );
142
- pos = pages [i ]-> index ;
143
- ret = radix_tree_delete (& brd -> brd_pages , pos );
144
- BUG_ON (!ret || ret != pages [i ]);
145
- __free_page (pages [i ]);
146
- }
147
-
148
- pos ++ ;
109
+ struct page * page ;
110
+ pgoff_t idx ;
149
111
150
- /*
151
- * It takes 3.4 seconds to remove 80GiB ramdisk.
152
- * So, we need cond_resched to avoid stalling the CPU.
153
- */
154
- cond_resched ();
112
+ xa_for_each (& brd -> brd_pages , idx , page ) {
113
+ __free_page (page );
114
+ cond_resched_rcu ();
115
+ }
155
116
156
- /*
157
- * This assumes radix_tree_gang_lookup always returns as
158
- * many pages as possible. If the radix-tree code changes,
159
- * so will this have to.
160
- */
161
- } while (nr_pages == FREE_BATCH );
117
+ xa_destroy (& brd -> brd_pages );
162
118
}
163
119
164
120
/*
@@ -372,8 +328,7 @@ static int brd_alloc(int i)
372
328
brd -> brd_number = i ;
373
329
list_add_tail (& brd -> brd_list , & brd_devices );
374
330
375
- spin_lock_init (& brd -> brd_lock );
376
- INIT_RADIX_TREE (& brd -> brd_pages , GFP_ATOMIC );
331
+ xa_init (& brd -> brd_pages );
377
332
378
333
snprintf (buf , DISK_NAME_LEN , "ram%d" , i );
379
334
if (!IS_ERR_OR_NULL (brd_debugfs_dir ))
0 commit comments