Skip to content

Commit ea1db79

Browse files
ming1axboe
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]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 47903fa commit ea1db79

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
@@ -5421,35 +5421,48 @@ static int ublk_ctrl_reg_buf(struct ublk_device *ub,
54215421
return ret;
54225422
}
54235423

5424-
static int __ublk_ctrl_unreg_buf(struct ublk_device *ub, int buf_index)
5424+
static void ublk_unpin_range_pages(unsigned long base_pfn,
5425+
unsigned long nr_pages)
5426+
{
5427+
#define UBLK_UNPIN_BATCH 32
5428+
struct page *pages[UBLK_UNPIN_BATCH];
5429+
unsigned long off;
5430+
5431+
for (off = 0; off < nr_pages; ) {
5432+
unsigned int batch = min_t(unsigned long,
5433+
nr_pages - off, UBLK_UNPIN_BATCH);
5434+
unsigned int j;
5435+
5436+
for (j = 0; j < batch; j++)
5437+
pages[j] = pfn_to_page(base_pfn + off + j);
5438+
unpin_user_pages(pages, batch);
5439+
off += batch;
5440+
}
5441+
}
5442+
5443+
/*
5444+
* Remove ranges from the maple tree matching buf_index, unpin pages
5445+
* and free range structs. If buf_index < 0, remove all ranges.
5446+
*/
5447+
static int ublk_shmem_remove_ranges(struct ublk_device *ub, int buf_index)
54255448
{
54265449
MA_STATE(mas, &ub->buf_tree, 0, ULONG_MAX);
54275450
struct ublk_buf_range *range;
5428-
struct page *pages[32];
54295451
int ret = -ENOENT;
54305452

54315453
mas_lock(&mas);
54325454
mas_for_each(&mas, range, ULONG_MAX) {
5433-
unsigned long base, nr, off;
5455+
unsigned long base, nr;
54345456

5435-
if (range->buf_index != buf_index)
5457+
if (buf_index >= 0 && range->buf_index != buf_index)
54365458
continue;
54375459

54385460
ret = 0;
54395461
base = mas.index;
54405462
nr = mas.last - base + 1;
54415463
mas_erase(&mas);
54425464

5443-
for (off = 0; off < nr; ) {
5444-
unsigned int batch = min_t(unsigned long,
5445-
nr - off, 32);
5446-
unsigned int j;
5447-
5448-
for (j = 0; j < batch; j++)
5449-
pages[j] = pfn_to_page(base + off + j);
5450-
unpin_user_pages(pages, batch);
5451-
off += batch;
5452-
}
5465+
ublk_unpin_range_pages(base, nr);
54535466
kfree(range);
54545467
}
54555468
mas_unlock(&mas);
@@ -5472,7 +5485,7 @@ static int ublk_ctrl_unreg_buf(struct ublk_device *ub,
54725485

54735486
memflags = ublk_lock_buf_tree(ub);
54745487

5475-
ret = __ublk_ctrl_unreg_buf(ub, index);
5488+
ret = ublk_shmem_remove_ranges(ub, index);
54765489
if (!ret)
54775490
ida_free(&ub->buf_ida, index);
54785491

@@ -5482,31 +5495,7 @@ static int ublk_ctrl_unreg_buf(struct ublk_device *ub,
54825495

54835496
static void ublk_buf_cleanup(struct ublk_device *ub)
54845497
{
5485-
MA_STATE(mas, &ub->buf_tree, 0, ULONG_MAX);
5486-
struct ublk_buf_range *range;
5487-
struct page *pages[32];
5488-
5489-
mas_lock(&mas);
5490-
mas_for_each(&mas, range, ULONG_MAX) {
5491-
unsigned long base = mas.index;
5492-
unsigned long nr = mas.last - base + 1;
5493-
unsigned long off;
5494-
5495-
mas_erase(&mas);
5496-
5497-
for (off = 0; off < nr; ) {
5498-
unsigned int batch = min_t(unsigned long,
5499-
nr - off, 32);
5500-
unsigned int j;
5501-
5502-
for (j = 0; j < batch; j++)
5503-
pages[j] = pfn_to_page(base + off + j);
5504-
unpin_user_pages(pages, batch);
5505-
off += batch;
5506-
}
5507-
kfree(range);
5508-
}
5509-
mas_unlock(&mas);
5498+
ublk_shmem_remove_ranges(ub, -1);
55105499
mtree_destroy(&ub->buf_tree);
55115500
ida_destroy(&ub->buf_ida);
55125501
}

0 commit comments

Comments
 (0)