diff options
author | Roger Pau Monne <roger.pau@citrix.com> | 2012-11-16 13:26:48 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-11-26 14:58:11 -0500 |
commit | 4d4f270f1880e52d89a33c944ee86f23d6c85541 (patch) | |
tree | 40371908023986591d0a3c32338f28f3bdc35255 /drivers/block/xen-blkback | |
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')
-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 a05961683efa..74374fb762aa 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, | |||
212 | return NULL; | 212 | return NULL; |
213 | } | 213 | } |
214 | 214 | ||
215 | static void free_persistent_gnts(struct rb_root *root, unsigned int num) | ||
216 | { | ||
217 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
218 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
219 | struct persistent_gnt *persistent_gnt; | ||
220 | int ret = 0; | ||
221 | int segs_to_unmap = 0; | ||
222 | |||
223 | foreach_grant(persistent_gnt, root, node) { | ||
224 | BUG_ON(persistent_gnt->handle == | ||
225 | BLKBACK_INVALID_HANDLE); | ||
226 | gnttab_set_unmap_op(&unmap[segs_to_unmap], | ||
227 | (unsigned long) pfn_to_kaddr(page_to_pfn( | ||
228 | persistent_gnt->page)), | ||
229 | GNTMAP_host_map, | ||
230 | persistent_gnt->handle); | ||
231 | |||
232 | pages[segs_to_unmap] = persistent_gnt->page; | ||
233 | rb_erase(&persistent_gnt->node, root); | ||
234 | kfree(persistent_gnt); | ||
235 | num--; | ||
236 | |||
237 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || | ||
238 | !rb_next(&persistent_gnt->node)) { | ||
239 | ret = gnttab_unmap_refs(unmap, NULL, pages, | ||
240 | segs_to_unmap); | ||
241 | BUG_ON(ret); | ||
242 | segs_to_unmap = 0; | ||
243 | } | ||
244 | } | ||
245 | BUG_ON(num != 0); | ||
246 | } | ||
247 | |||
215 | /* | 248 | /* |
216 | * Retrieve from the 'pending_reqs' a free pending_req structure to be used. | 249 | * Retrieve from the 'pending_reqs' a free pending_req structure to be used. |
217 | */ | 250 | */ |
@@ -358,11 +391,6 @@ int xen_blkif_schedule(void *arg) | |||
358 | { | 391 | { |
359 | struct xen_blkif *blkif = arg; | 392 | struct xen_blkif *blkif = arg; |
360 | struct xen_vbd *vbd = &blkif->vbd; | 393 | struct xen_vbd *vbd = &blkif->vbd; |
361 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
362 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
363 | struct persistent_gnt *persistent_gnt; | ||
364 | int ret = 0; | ||
365 | int segs_to_unmap = 0; | ||
366 | 394 | ||
367 | xen_blkif_get(blkif); | 395 | xen_blkif_get(blkif); |
368 | 396 | ||
@@ -391,34 +419,12 @@ int xen_blkif_schedule(void *arg) | |||
391 | } | 419 | } |
392 | 420 | ||
393 | /* Free all persistent grant pages */ | 421 | /* Free all persistent grant pages */ |
394 | if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) { | 422 | if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) |
395 | foreach_grant(persistent_gnt, &blkif->persistent_gnts, node) { | 423 | free_persistent_gnts(&blkif->persistent_gnts, |
396 | BUG_ON(persistent_gnt->handle == | 424 | blkif->persistent_gnt_c); |
397 | BLKBACK_INVALID_HANDLE); | ||
398 | gnttab_set_unmap_op(&unmap[segs_to_unmap], | ||
399 | (unsigned long) pfn_to_kaddr(page_to_pfn( | ||
400 | persistent_gnt->page)), | ||
401 | GNTMAP_host_map, | ||
402 | persistent_gnt->handle); | ||
403 | |||
404 | pages[segs_to_unmap] = persistent_gnt->page; | ||
405 | rb_erase(&persistent_gnt->node, | ||
406 | &blkif->persistent_gnts); | ||
407 | kfree(persistent_gnt); | ||
408 | blkif->persistent_gnt_c--; | ||
409 | |||
410 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || | ||
411 | !rb_next(&persistent_gnt->node)) { | ||
412 | ret = gnttab_unmap_refs(unmap, NULL, pages, | ||
413 | segs_to_unmap); | ||
414 | BUG_ON(ret); | ||
415 | segs_to_unmap = 0; | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | 425 | ||
420 | BUG_ON(blkif->persistent_gnt_c != 0); | ||
421 | BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); | 426 | BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); |
427 | blkif->persistent_gnt_c = 0; | ||
422 | 428 | ||
423 | if (log_stats) | 429 | if (log_stats) |
424 | print_stats(blkif); | 430 | print_stats(blkif); |