| @@ -152,6 +152,10 @@ static unsigned int xen_blkif_max_ring_order; · 151 unmodified lines |
| 152 | module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444); | 152 | module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444); |
| 153 | MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring"); | 153 | MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring"); |
| 154 | | 154 | |
| | 155 | static bool __read_mostly xen_blkif_trusted = true; |
| | 156 | module_param_named(trusted, xen_blkif_trusted, bool, 0644); |
| | 157 | MODULE_PARM_DESC(trusted, "Is the backend trusted"); |
| | 158 | |
| 155 | #define BLK_RING_SIZE(info) \ | 159 | #define BLK_RING_SIZE(info) \ |
| 156 | __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages) | 160 | __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages) |
| 157 | | 161 | |
| @@ -210,6 +214,7 @@ struct blkfront_info · 52 unmodified lines |
| 210 | unsigned int feature_discard:1; | 214 | unsigned int feature_discard:1; |
| 211 | unsigned int feature_secdiscard:1; | 215 | unsigned int feature_secdiscard:1; |
| 212 | unsigned int feature_persistent:1; | 216 | unsigned int feature_persistent:1; |
| | 217 | unsigned int bounce:1; |
| 213 | unsigned int discard_granularity; | 218 | unsigned int discard_granularity; |
| 214 | unsigned int discard_alignment; | 219 | unsigned int discard_alignment; |
| 215 | /* Number of 4KB segments handled */ | 220 | /* Number of 4KB segments handled */ |
| @@ -310,8 +315,8 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num) · 94 unmodified lines |
| 310 | if (!gnt_list_entry) | 315 | if (!gnt_list_entry) |
| 311 | goto out_of_memory; | 316 | goto out_of_memory; |
| 312 | | 317 | |
| 313 | if (info->feature_persistent) { | 318 | if (info->bounce) { |
| 314 | granted_page = alloc_page(GFP_NOIO); | 319 | granted_page = alloc_page(GFP_NOIO | __GFP_ZERO); |
| 315 | if (!granted_page) { | 320 | if (!granted_page) { |
| 316 | kfree(gnt_list_entry); | 321 | kfree(gnt_list_entry); |
| 317 | goto out_of_memory; | 322 | goto out_of_memory; |
| @@ -330,7 +335,7 @@ out_of_memory: · 12 unmodified lines |
| 330 | list_for_each_entry_safe(gnt_list_entry, n, | 335 | list_for_each_entry_safe(gnt_list_entry, n, |
| 331 | &rinfo->grants, node) { | 336 | &rinfo->grants, node) { |
| 332 | list_del(&gnt_list_entry->node); | 337 | list_del(&gnt_list_entry->node); |
| 333 | if (info->feature_persistent) | 338 | if (info->bounce) |
| 334 | __free_page(gnt_list_entry->page); | 339 | __free_page(gnt_list_entry->page); |
| 335 | kfree(gnt_list_entry); | 340 | kfree(gnt_list_entry); |
| 336 | i--; | 341 | i--; |
| @@ -376,7 +381,7 @@ static struct grant *get_grant(grant_ref_t *gref_head, · 39 unmodified lines |
| 376 | /* Assign a gref to this page */ | 381 | /* Assign a gref to this page */ |
| 377 | gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); | 382 | gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); |
| 378 | BUG_ON(gnt_list_entry->gref == -ENOSPC); | 383 | BUG_ON(gnt_list_entry->gref == -ENOSPC); |
| 379 | if (info->feature_persistent) | 384 | if (info->bounce) |
| 380 | grant_foreign_access(gnt_list_entry, info); | 385 | grant_foreign_access(gnt_list_entry, info); |
| 381 | else { | 386 | else { |
| 382 | /* Grant access to the GFN passed by the caller */ | 387 | /* Grant access to the GFN passed by the caller */ |
| @@ -400,7 +405,7 @@ static struct grant *get_indirect_grant(grant_ref_t *gref_head, · 17 unmodified lines |
| 400 | /* Assign a gref to this page */ | 405 | /* Assign a gref to this page */ |
| 401 | gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); | 406 | gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); |
| 402 | BUG_ON(gnt_list_entry->gref == -ENOSPC); | 407 | BUG_ON(gnt_list_entry->gref == -ENOSPC); |
| 403 | if (!info->feature_persistent) { | 408 | if (!info->bounce) { |
| 404 | struct page *indirect_page; | 409 | struct page *indirect_page; |
| 405 | | 410 | |
| 406 | /* Fetch a pre-allocated page to use for indirect grefs */ | 411 | /* Fetch a pre-allocated page to use for indirect grefs */ |
| @@ -703,7 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri · 296 unmodified lines |
| 703 | .grant_idx = 0, | 708 | .grant_idx = 0, |
| 704 | .segments = NULL, | 709 | .segments = NULL, |
| 705 | .rinfo = rinfo, | 710 | .rinfo = rinfo, |
| 706 | .need_copy = rq_data_dir(req) && info->feature_persistent, | 711 | .need_copy = rq_data_dir(req) && info->bounce, |
| 707 | }; | 712 | }; |
| 708 | | 713 | |
| 709 | /* | 714 | /* |
| @@ -981,11 +986,12 @@ static void xlvbd_flush(struct blkfront_info *info) · 271 unmodified lines |
| 981 | { | 986 | { |
| 982 | blk_queue_write_cache(info->rq, info->feature_flush ? true : false, | 987 | blk_queue_write_cache(info->rq, info->feature_flush ? true : false, |
| 983 | info->feature_fua ? true : false); | 988 | info->feature_fua ? true : false); |
| 984 | pr_info("blkfront: %s: %s %s %s %s %s\n", | 989 | pr_info("blkfront: %s: %s %s %s %s %s %s %s\n", |
| 985 | info->gd->disk_name, flush_info(info), | 990 | info->gd->disk_name, flush_info(info), |
| 986 | "persistent grants:", info->feature_persistent ? | 991 | "persistent grants:", info->feature_persistent ? |
| 987 | "enabled;" : "disabled;", "indirect descriptors:", | 992 | "enabled;" : "disabled;", "indirect descriptors:", |
| 988 | info->max_indirect_segments ? "enabled;" : "disabled;"); | 993 | info->max_indirect_segments ? "enabled;" : "disabled;", |
| | 994 | "bounce buffer:", info->bounce ? "enabled" : "disabled;"); |
| 989 | } | 995 | } |
| 990 | | 996 | |
| 991 | static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) | 997 | static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) |
| @@ -1207,7 +1213,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) · 215 unmodified lines |
| 1207 | if (!list_empty(&rinfo->indirect_pages)) { | 1213 | if (!list_empty(&rinfo->indirect_pages)) { |
| 1208 | struct page *indirect_page, *n; | 1214 | struct page *indirect_page, *n; |
| 1209 | | 1215 | |
| 1210 | BUG_ON(info->feature_persistent); | 1216 | BUG_ON(info->bounce); |
| 1211 | list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { | 1217 | list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { |
| 1212 | list_del(&indirect_page->lru); | 1218 | list_del(&indirect_page->lru); |
| 1213 | __free_page(indirect_page); | 1219 | __free_page(indirect_page); |
| @@ -1224,7 +1230,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) · 10 unmodified lines |
| 1224 | NULL); | 1230 | NULL); |
| 1225 | rinfo->persistent_gnts_c--; | 1231 | rinfo->persistent_gnts_c--; |
| 1226 | } | 1232 | } |
| 1227 | if (info->feature_persistent) | 1233 | if (info->bounce) |
| 1228 | __free_page(persistent_gnt->page); | 1234 | __free_page(persistent_gnt->page); |
| 1229 | kfree(persistent_gnt); | 1235 | kfree(persistent_gnt); |
| 1230 | } | 1236 | } |
| @@ -1245,7 +1251,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) · 14 unmodified lines |
| 1245 | for (j = 0; j < segs; j++) { | 1251 | for (j = 0; j < segs; j++) { |
| 1246 | persistent_gnt = rinfo->shadow[i].grants_used[j]; | 1252 | persistent_gnt = rinfo->shadow[i].grants_used[j]; |
| 1247 | gnttab_end_foreign_access(persistent_gnt->gref, NULL); | 1253 | gnttab_end_foreign_access(persistent_gnt->gref, NULL); |
| 1248 | if (info->feature_persistent) | 1254 | if (info->bounce) |
| 1249 | __free_page(persistent_gnt->page); | 1255 | __free_page(persistent_gnt->page); |
| 1250 | kfree(persistent_gnt); | 1256 | kfree(persistent_gnt); |
| 1251 | } | 1257 | } |
| @@ -1428,7 +1434,7 @@ static int blkif_completion(unsigned long *id, · 176 unmodified lines |
| 1428 | data.s = s; | 1434 | data.s = s; |
| 1429 | num_sg = s->num_sg; | 1435 | num_sg = s->num_sg; |
| 1430 | | 1436 | |
| 1431 | if (bret->operation == BLKIF_OP_READ && info->feature_persistent) { | 1437 | if (bret->operation == BLKIF_OP_READ && info->bounce) { |
| 1432 | for_each_sg(s->sg, sg, num_sg, i) { | 1438 | for_each_sg(s->sg, sg, num_sg, i) { |
| 1433 | BUG_ON(sg->offset + sg->length > PAGE_SIZE); | 1439 | BUG_ON(sg->offset + sg->length > PAGE_SIZE); |
| 1434 | | 1440 | |
| @@ -1487,7 +1493,7 @@ static int blkif_completion(unsigned long *id, · 52 unmodified lines |
| 1487 | * Add the used indirect page back to the list of | 1493 | * Add the used indirect page back to the list of |
| 1488 | * available pages for indirect grefs. | 1494 | * available pages for indirect grefs. |
| 1489 | */ | 1495 | */ |
| 1490 | if (!info->feature_persistent) { | 1496 | if (!info->bounce) { |
| 1491 | indirect_page = s->indirect_grants[i]->page; | 1497 | indirect_page = s->indirect_grants[i]->page; |
| 1492 | list_add(&indirect_page->lru, &rinfo->indirect_pages); | 1498 | list_add(&indirect_page->lru, &rinfo->indirect_pages); |
| 1493 | } | 1499 | } |
| @@ -1764,6 +1770,10 @@ static int talk_to_blkback(struct xenbus_device *dev, · 270 unmodified lines |
| 1764 | if (!info) | 1770 | if (!info) |
| 1765 | return -ENODEV; | 1771 | return -ENODEV; |
| 1766 | | 1772 | |
| | 1773 | /* Check if backend is trusted. */ |
| | 1774 | info->bounce = !xen_blkif_trusted || |
| | 1775 | !xenbus_read_unsigned(dev->nodename, "trusted", 1); |
| | 1776 | |
| 1767 | max_page_order = xenbus_read_unsigned(info->xbdev->otherend, | 1777 | max_page_order = xenbus_read_unsigned(info->xbdev->otherend, |
| 1768 | "max-ring-page-order", 0); | 1778 | "max-ring-page-order", 0); |
| 1769 | ring_page_order = min(xen_blkif_max_ring_order, max_page_order); | 1779 | ring_page_order = min(xen_blkif_max_ring_order, max_page_order); |
| @@ -2173,17 +2183,18 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) · 403 unmodified lines |
| 2173 | if (err) | 2183 | if (err) |
| 2174 | goto out_of_memory; | 2184 | goto out_of_memory; |
| 2175 | | 2185 | |
| 2176 | if (!info->feature_persistent && info->max_indirect_segments) { | 2186 | if (!info->bounce && info->max_indirect_segments) { |
| 2177 | /* | 2187 | /* |
| 2178 | * We are using indirect descriptors but not persistent | 2188 | * We are using indirect descriptors but don't have a bounce |
| 2179 | * grants, we need to allocate a set of pages that can be | 2189 | * buffer, we need to allocate a set of pages that can be |
| 2180 | * used for mapping indirect grefs | 2190 | * used for mapping indirect grefs |
| 2181 | */ | 2191 | */ |
| 2182 | int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info); | 2192 | int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info); |
| 2183 | | 2193 | |
| 2184 | BUG_ON(!list_empty(&rinfo->indirect_pages)); | 2194 | BUG_ON(!list_empty(&rinfo->indirect_pages)); |
| 2185 | for (i = 0; i < num; i++) { | 2195 | for (i = 0; i < num; i++) { |
| 2186 | struct page *indirect_page = alloc_page(GFP_KERNEL); | 2196 | struct page *indirect_page = alloc_page(GFP_KERNEL | |
| | 2197 | __GFP_ZERO); |
| 2187 | if (!indirect_page) | 2198 | if (!indirect_page) |
| 2188 | goto out_of_memory; | 2199 | goto out_of_memory; |
| 2189 | list_add(&indirect_page->lru, &rinfo->indirect_pages); | 2200 | list_add(&indirect_page->lru, &rinfo->indirect_pages); |
| @@ -2276,6 +2287,8 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) · 86 unmodified lines |
| 2276 | info->feature_persistent = | 2287 | info->feature_persistent = |
| 2277 | !!xenbus_read_unsigned(info->xbdev->otherend, | 2288 | !!xenbus_read_unsigned(info->xbdev->otherend, |
| 2278 | "feature-persistent", 0); | 2289 | "feature-persistent", 0); |
| | 2290 | if (info->feature_persistent) |
| | 2291 | info->bounce = true; |
| 2279 | | 2292 | |
| 2280 | indirect_segments = xenbus_read_unsigned(info->xbdev->otherend, | 2293 | indirect_segments = xenbus_read_unsigned(info->xbdev->otherend, |
| 2281 | "feature-max-indirect-segments", 0); | 2294 | "feature-max-indirect-segments", 0); |
| @@ -2547,6 +2560,13 @@ static void blkfront_delay_work(struct work_struct *work) · 265 unmodified lines |
| 2547 | struct blkfront_info *info; | 2560 | struct blkfront_info *info; |
| 2548 | bool need_schedule_work = false; | 2561 | bool need_schedule_work = false; |
| 2549 | | 2562 | |
| | 2563 | /* |
| | 2564 | * Note that when using bounce buffers but not persistent grants |
| | 2565 | * there's no need to run blkfront_delay_work because grants are |
| | 2566 | * revoked in blkif_completion or else an error is reported and the |
| | 2567 | * connection is closed. |
| | 2568 | */ |
| | 2569 | |
| 2550 | mutex_lock(&blkfront_mutex); | 2570 | mutex_lock(&blkfront_mutex); |
| 2551 | | 2571 | |
| 2552 | list_for_each_entry(info, &info_list, info_list) { | 2572 | list_for_each_entry(info, &info_list, info_list) { |