Skip to content

Commit 48b9507

Browse files
ming1kawasaki
authored andcommitted
ublk: refactor common helper ublk_shmem_remove_ranges()
Extract the shared walk+erase+unpin+kfree loop into ublk_shmem_remove_ranges(). When buf_index >= 0, only ranges matching that index are removed; when buf_index < 0, all ranges are removed. Also extract ublk_unpin_range_pages() to share the page unpinning loop. Convert both __ublk_ctrl_unreg_buf() and ublk_buf_cleanup() to use the new helper. Signed-off-by: Ming Lei <[email protected]>
1 parent 4027807 commit 48b9507

1 file changed

Lines changed: 29 additions & 40 deletions

File tree

drivers/block/ublk_drv.c

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5413,35 +5413,48 @@ static int ublk_ctrl_reg_buf(struct ublk_device *ub,
54135413
return ret;
54145414
}
54155415

5416-
static int __ublk_ctrl_unreg_buf(struct ublk_device *ub, int buf_index)
5416+
static void ublk_unpin_range_pages(unsigned long base_pfn,
5417+
unsigned long nr_pages)
5418+
{
5419+
#define UBLK_UNPIN_BATCH 32
5420+
struct page *pages[UBLK_UNPIN_BATCH];
5421+
unsigned long off;
5422+
5423+
for (off = 0; off < nr_pages; ) {
5424+
unsigned int batch = min_t(unsigned long,
5425+
nr_pages - off, UBLK_UNPIN_BATCH);
5426+
unsigned int j;
5427+
5428+
for (j = 0; j < batch; j++)
5429+
pages[j] = pfn_to_page(base_pfn + off + j);
5430+
unpin_user_pages(pages, batch);
5431+
off += batch;
5432+
}
5433+
}
5434+
5435+
/*
5436+
* Remove ranges from the maple tree matching buf_index, unpin pages
5437+
* and free range structs. If buf_index < 0, remove all ranges.
5438+
*/
5439+
static int ublk_shmem_remove_ranges(struct ublk_device *ub, int buf_index)
54175440
{
54185441
MA_STATE(mas, &ub->buf_tree, 0, ULONG_MAX);
54195442
struct ublk_buf_range *range;
5420-
struct page *pages[32];
54215443
int ret = -ENOENT;
54225444

54235445
mas_lock(&mas);
54245446
mas_for_each(&mas, range, ULONG_MAX) {
5425-
unsigned long base, nr, off;
5447+
unsigned long base, nr;
54265448

5427-
if (range->buf_index != buf_index)
5449+
if (buf_index >= 0 && range->buf_index != buf_index)
54285450
continue;
54295451

54305452
ret = 0;
54315453
base = mas.index;
54325454
nr = mas.last - base + 1;
54335455
mas_erase(&mas);
54345456

5435-
for (off = 0; off < nr; ) {
5436-
unsigned int batch = min_t(unsigned long,
5437-
nr - off, 32);
5438-
unsigned int j;
5439-
5440-
for (j = 0; j < batch; j++)
5441-
pages[j] = pfn_to_page(base + off + j);
5442-
unpin_user_pages(pages, batch);
5443-
off += batch;
5444-
}
5457+
ublk_unpin_range_pages(base, nr);
54455458
kfree(range);
54465459
}
54475460
mas_unlock(&mas);
@@ -5464,7 +5477,7 @@ static int ublk_ctrl_unreg_buf(struct ublk_device *ub,
54645477

54655478
memflags = ublk_lock_buf_tree(ub);
54665479

5467-
ret = __ublk_ctrl_unreg_buf(ub, index);
5480+
ret = ublk_shmem_remove_ranges(ub, index);
54685481
if (!ret)
54695482
ida_free(&ub->buf_ida, index);
54705483

@@ -5474,31 +5487,7 @@ static int ublk_ctrl_unreg_buf(struct ublk_device *ub,
54745487

54755488
static void ublk_buf_cleanup(struct ublk_device *ub)
54765489
{
5477-
MA_STATE(mas, &ub->buf_tree, 0, ULONG_MAX);
5478-
struct ublk_buf_range *range;
5479-
struct page *pages[32];
5480-
5481-
mas_lock(&mas);
5482-
mas_for_each(&mas, range, ULONG_MAX) {
5483-
unsigned long base = mas.index;
5484-
unsigned long nr = mas.last - base + 1;
5485-
unsigned long off;
5486-
5487-
mas_erase(&mas);
5488-
5489-
for (off = 0; off < nr; ) {
5490-
unsigned int batch = min_t(unsigned long,
5491-
nr - off, 32);
5492-
unsigned int j;
5493-
5494-
for (j = 0; j < batch; j++)
5495-
pages[j] = pfn_to_page(base + off + j);
5496-
unpin_user_pages(pages, batch);
5497-
off += batch;
5498-
}
5499-
kfree(range);
5500-
}
5501-
mas_unlock(&mas);
5490+
ublk_shmem_remove_ranges(ub, -1);
55025491
mtree_destroy(&ub->buf_tree);
55035492
ida_destroy(&ub->buf_ida);
55045493
}

0 commit comments

Comments
 (0)