diff options
author | Roger Pau Monne <roger.pau@citrix.com> | 2012-11-16 19:26:48 +0100 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-11-26 14:58:11 -0500 |
commit | 4d4f270f1880e52d89a33c944ee86f23d6c85541 (patch) | |
tree | 40371908023986591d0a3c32338f28f3bdc35255 /drivers/block/xen-blkback/blkback.c | |
parent | cb5bd4d19b46c220b1ac8462a3da01767dd99488 (diff) |
xen-blkback: move free persistent grants code
Move the code that frees persistent grants from the red-black tree
to a function. This will make it easier for other consumers to move
this to a common place.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block/xen-blkback/blkback.c')
-rw-r--r-- | drivers/block/xen-blkback/blkback.c | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index a05961683ef..74374fb762a 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -212,6 +212,39 @@ static struct persistent_gnt *get_persistent_gnt(struct rb_root *root, return NULL; } +static void free_persistent_gnts(struct rb_root *root, unsigned int num) +{ + struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct persistent_gnt *persistent_gnt; + int ret = 0; + int segs_to_unmap = 0; + + foreach_grant(persistent_gnt, root, node) { + BUG_ON(persistent_gnt->handle == + BLKBACK_INVALID_HANDLE); + gnttab_set_unmap_op(&unmap[segs_to_unmap], + (unsigned long) pfn_to_kaddr(page_to_pfn( + persistent_gnt->page)), + GNTMAP_host_map, + persistent_gnt->handle); + + pages[segs_to_unmap] = persistent_gnt->page; + rb_erase(&persistent_gnt->node, root); + kfree(persistent_gnt); + num--; + + if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || + !rb_next(&persistent_gnt->node)) { + ret = gnttab_unmap_refs(unmap, NULL, pages, + segs_to_unmap); + BUG_ON(ret); + segs_to_unmap = 0; + } + } + BUG_ON(num != 0); +} + /* * Retrieve from the 'pending_reqs' a free pending_req structure to be used. */ @@ -358,11 +391,6 @@ int xen_blkif_schedule(void *arg) { struct xen_blkif *blkif = arg; struct xen_vbd *vbd = &blkif->vbd; - struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - struct persistent_gnt *persistent_gnt; - int ret = 0; - int segs_to_unmap = 0; xen_blkif_get(blkif); @@ -391,34 +419,12 @@ int xen_blkif_schedule(void *arg) } /* Free all persistent grant pages */ - if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) { - foreach_grant(persistent_gnt, &blkif->persistent_gnts, node) { - BUG_ON(persistent_gnt->handle == - BLKBACK_INVALID_HANDLE); - gnttab_set_unmap_op(&unmap[segs_to_unmap], - (unsigned long) pfn_to_kaddr(page_to_pfn( - persistent_gnt->page)), - GNTMAP_host_map, - persistent_gnt->handle); - - pages[segs_to_unmap] = persistent_gnt->page; - rb_erase(&persistent_gnt->node, - &blkif->persistent_gnts); - kfree(persistent_gnt); - blkif->persistent_gnt_c--; - - if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || - !rb_next(&persistent_gnt->node)) { - ret = gnttab_unmap_refs(unmap, NULL, pages, - segs_to_unmap); - BUG_ON(ret); - segs_to_unmap = 0; - } - } - } + if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) + free_persistent_gnts(&blkif->persistent_gnts, + blkif->persistent_gnt_c); - BUG_ON(blkif->persistent_gnt_c != 0); BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); + blkif->persistent_gnt_c = 0; if (log_stats) print_stats(blkif); |