Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
"Final round of fixes for this merge window - some of this has come up
after the initial pull request, and some of it was put in a post-merge
branch before the merge window.

This contains:

- Fix for a bad check for an error on dma mapping in the mtip32xx
driver, from Alexey Khoroshilov.

- A set of fixes for lightnvm, from Javier, Matias, and Wenwei.

- An NVMe completion record corruption fix from Marta, ensuring that
we read things in the right order.

- Two writeback fixes from Tejun, marked for stable@ as well.

- A blk-mq sw queue iterator fix from Thomas, fixing an oops for
sparse CPU maps. They hit this in the hot plug/unplug rework"

* 'for-linus' of git://git.kernel.dk/linux-block:
nvme: avoid cqe corruption when update at the same time as read
writeback, cgroup: fix use of the wrong bdi_writeback which mismatches the inode
writeback, cgroup: fix premature wb_put() in locked_inode_to_wb_and_lock_list()
blk-mq: Use proper cpumask iterator
mtip32xx: fix checks for dma mapping errors
lightnvm: do not load L2P table if not supported
lightnvm: do not reserve lun on l2p loading
nvme: lightnvm: return ppa completion status
lightnvm: add a bitmap of luns
lightnvm: specify target's logical address area
null_blk: add lightnvm null_blk device to the nullb_list

+251 -78
+4 -2
block/blk-mq-sysfs.c
··· 416 416 static void blk_mq_sysfs_init(struct request_queue *q) 417 417 { 418 418 struct blk_mq_ctx *ctx; 419 - int i; 419 + int cpu; 420 420 421 421 kobject_init(&q->mq_kobj, &blk_mq_ktype); 422 422 423 - queue_for_each_ctx(q, ctx, i) 423 + for_each_possible_cpu(cpu) { 424 + ctx = per_cpu_ptr(q->queue_ctx, cpu); 424 425 kobject_init(&ctx->kobj, &blk_mq_ctx_ktype); 426 + } 425 427 } 426 428 427 429 int blk_mq_register_disk(struct gendisk *disk)
+2 -1
block/blk-mq.c
··· 1798 1798 /* 1799 1799 * Map software to hardware queues 1800 1800 */ 1801 - queue_for_each_ctx(q, ctx, i) { 1801 + for_each_possible_cpu(i) { 1802 1802 /* If the cpu isn't online, the cpu is mapped to first hctx */ 1803 1803 if (!cpumask_test_cpu(i, online_mask)) 1804 1804 continue; 1805 1805 1806 + ctx = per_cpu_ptr(q->queue_ctx, i); 1806 1807 hctx = q->mq_ops->map_queue(q, i); 1807 1808 1808 1809 cpumask_set_cpu(i, hctx->cpumask);
+2 -2
drivers/block/mtip32xx/mtip32xx.c
··· 2051 2051 outbuf, 2052 2052 taskout, 2053 2053 DMA_TO_DEVICE); 2054 - if (outbuf_dma == 0) { 2054 + if (pci_dma_mapping_error(dd->pdev, outbuf_dma)) { 2055 2055 err = -ENOMEM; 2056 2056 goto abort; 2057 2057 } ··· 2068 2068 inbuf_dma = pci_map_single(dd->pdev, 2069 2069 inbuf, 2070 2070 taskin, DMA_FROM_DEVICE); 2071 - if (inbuf_dma == 0) { 2071 + if (pci_dma_mapping_error(dd->pdev, inbuf_dma)) { 2072 2072 err = -ENOMEM; 2073 2073 goto abort; 2074 2074 }
+2 -1
drivers/block/null_blk.c
··· 742 742 743 743 add_disk(disk); 744 744 745 + done: 745 746 mutex_lock(&lock); 746 747 list_add_tail(&nullb->list, &nullb_list); 747 748 mutex_unlock(&lock); 748 - done: 749 + 749 750 return 0; 750 751 751 752 out_cleanup_lightnvm:
+7
drivers/lightnvm/core.c
··· 464 464 dev->nr_luns = dev->luns_per_chnl * dev->nr_chnls; 465 465 466 466 dev->total_secs = dev->nr_luns * dev->sec_per_lun; 467 + dev->lun_map = kcalloc(BITS_TO_LONGS(dev->nr_luns), 468 + sizeof(unsigned long), GFP_KERNEL); 469 + if (!dev->lun_map) 470 + return -ENOMEM; 467 471 INIT_LIST_HEAD(&dev->online_targets); 468 472 mutex_init(&dev->mlock); 473 + spin_lock_init(&dev->lock); 469 474 470 475 return 0; 471 476 } ··· 590 585 591 586 return 0; 592 587 err_init: 588 + kfree(dev->lun_map); 593 589 kfree(dev); 594 590 return ret; 595 591 } ··· 613 607 up_write(&nvm_lock); 614 608 615 609 nvm_exit(dev); 610 + kfree(dev->lun_map); 616 611 kfree(dev); 617 612 } 618 613 EXPORT_SYMBOL(nvm_unregister);
+83 -1
drivers/lightnvm/gennvm.c
··· 20 20 21 21 #include "gennvm.h" 22 22 23 + static int gennvm_get_area(struct nvm_dev *dev, sector_t *lba, sector_t len) 24 + { 25 + struct gen_nvm *gn = dev->mp; 26 + struct gennvm_area *area, *prev, *next; 27 + sector_t begin = 0; 28 + sector_t max_sectors = (dev->sec_size * dev->total_secs) >> 9; 29 + 30 + if (len > max_sectors) 31 + return -EINVAL; 32 + 33 + area = kmalloc(sizeof(struct gennvm_area), GFP_KERNEL); 34 + if (!area) 35 + return -ENOMEM; 36 + 37 + prev = NULL; 38 + 39 + spin_lock(&dev->lock); 40 + list_for_each_entry(next, &gn->area_list, list) { 41 + if (begin + len > next->begin) { 42 + begin = next->end; 43 + prev = next; 44 + continue; 45 + } 46 + break; 47 + } 48 + 49 + if ((begin + len) > max_sectors) { 50 + spin_unlock(&dev->lock); 51 + kfree(area); 52 + return -EINVAL; 53 + } 54 + 55 + area->begin = *lba = begin; 56 + area->end = begin + len; 57 + 58 + if (prev) /* insert into sorted order */ 59 + list_add(&area->list, &prev->list); 60 + else 61 + list_add(&area->list, &gn->area_list); 62 + spin_unlock(&dev->lock); 63 + 64 + return 0; 65 + } 66 + 67 + static void gennvm_put_area(struct nvm_dev *dev, sector_t begin) 68 + { 69 + struct gen_nvm *gn = dev->mp; 70 + struct gennvm_area *area; 71 + 72 + spin_lock(&dev->lock); 73 + list_for_each_entry(area, &gn->area_list, list) { 74 + if (area->begin != begin) 75 + continue; 76 + 77 + list_del(&area->list); 78 + spin_unlock(&dev->lock); 79 + kfree(area); 80 + return; 81 + } 82 + spin_unlock(&dev->lock); 83 + } 84 + 23 85 static void gennvm_blocks_free(struct nvm_dev *dev) 24 86 { 25 87 struct gen_nvm *gn = dev->mp; ··· 257 195 } 258 196 } 259 197 260 - if (dev->ops->get_l2p_tbl) { 198 + if ((dev->identity.dom & NVM_RSP_L2P) && dev->ops->get_l2p_tbl) { 261 199 ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_secs, 262 200 gennvm_block_map, dev); 263 201 if (ret) { ··· 291 229 292 230 gn->dev = dev; 293 231 gn->nr_luns = dev->nr_luns; 232 + INIT_LIST_HEAD(&gn->area_list); 294 233 dev->mp = gn; 295 234 296 235 ret = gennvm_luns_init(dev, gn); ··· 482 419 return nvm_erase_ppa(dev, &addr, 1); 483 420 } 484 421 422 + static int gennvm_reserve_lun(struct nvm_dev *dev, int lunid) 423 + { 424 + return test_and_set_bit(lunid, dev->lun_map); 425 + } 426 + 427 + static void gennvm_release_lun(struct nvm_dev *dev, int lunid) 428 + { 429 + WARN_ON(!test_and_clear_bit(lunid, dev->lun_map)); 430 + } 431 + 485 432 static struct nvm_lun *gennvm_get_lun(struct nvm_dev *dev, int lunid) 486 433 { 487 434 struct gen_nvm *gn = dev->mp; 435 + 436 + if (unlikely(lunid >= dev->nr_luns)) 437 + return NULL; 488 438 489 439 return &gn->luns[lunid].vlun; 490 440 } ··· 540 464 .erase_blk = gennvm_erase_blk, 541 465 542 466 .get_lun = gennvm_get_lun, 467 + .reserve_lun = gennvm_reserve_lun, 468 + .release_lun = gennvm_release_lun, 543 469 .lun_info_print = gennvm_lun_info_print, 470 + 471 + .get_area = gennvm_get_area, 472 + .put_area = gennvm_put_area, 473 + 544 474 }; 545 475 546 476 static int __init gennvm_module_init(void)
+6
drivers/lightnvm/gennvm.h
··· 39 39 40 40 int nr_luns; 41 41 struct gen_lun *luns; 42 + struct list_head area_list; 42 43 }; 43 44 45 + struct gennvm_area { 46 + struct list_head list; 47 + sector_t begin; 48 + sector_t end; /* end is excluded */ 49 + }; 44 50 #define gennvm_for_each_lun(bm, lun, i) \ 45 51 for ((i) = 0, lun = &(bm)->luns[0]; \ 46 52 (i) < (bm)->nr_luns; (i)++, lun = &(bm)->luns[(i)])
+78 -31
drivers/lightnvm/rrpc.c
··· 965 965 966 966 static void rrpc_gc_free(struct rrpc *rrpc) 967 967 { 968 - struct rrpc_lun *rlun; 969 - int i; 970 - 971 968 if (rrpc->krqd_wq) 972 969 destroy_workqueue(rrpc->krqd_wq); 973 970 974 971 if (rrpc->kgc_wq) 975 972 destroy_workqueue(rrpc->kgc_wq); 976 - 977 - if (!rrpc->luns) 978 - return; 979 - 980 - for (i = 0; i < rrpc->nr_luns; i++) { 981 - rlun = &rrpc->luns[i]; 982 - 983 - if (!rlun->blocks) 984 - break; 985 - vfree(rlun->blocks); 986 - } 987 973 } 988 974 989 975 static int rrpc_gc_init(struct rrpc *rrpc) ··· 1039 1053 { 1040 1054 struct nvm_dev *dev = rrpc->dev; 1041 1055 sector_t i; 1056 + u64 slba; 1042 1057 int ret; 1058 + 1059 + slba = rrpc->soffset >> (ilog2(dev->sec_size) - 9); 1043 1060 1044 1061 rrpc->trans_map = vzalloc(sizeof(struct rrpc_addr) * rrpc->nr_sects); 1045 1062 if (!rrpc->trans_map) ··· 1065 1076 return 0; 1066 1077 1067 1078 /* Bring up the mapping table from device */ 1068 - ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_secs, rrpc_l2p_update, 1079 + ret = dev->ops->get_l2p_tbl(dev, slba, rrpc->nr_sects, rrpc_l2p_update, 1069 1080 rrpc); 1070 1081 if (ret) { 1071 1082 pr_err("nvm: rrpc: could not read L2P table.\n"); ··· 1074 1085 1075 1086 return 0; 1076 1087 } 1077 - 1078 1088 1079 1089 /* Minimum pages needed within a lun */ 1080 1090 #define PAGE_POOL_SIZE 16 ··· 1129 1141 1130 1142 static void rrpc_luns_free(struct rrpc *rrpc) 1131 1143 { 1144 + struct nvm_dev *dev = rrpc->dev; 1145 + struct nvm_lun *lun; 1146 + struct rrpc_lun *rlun; 1147 + int i; 1148 + 1149 + if (!rrpc->luns) 1150 + return; 1151 + 1152 + for (i = 0; i < rrpc->nr_luns; i++) { 1153 + rlun = &rrpc->luns[i]; 1154 + lun = rlun->parent; 1155 + if (!lun) 1156 + break; 1157 + dev->mt->release_lun(dev, lun->id); 1158 + vfree(rlun->blocks); 1159 + } 1160 + 1132 1161 kfree(rrpc->luns); 1133 1162 } 1134 1163 ··· 1153 1148 { 1154 1149 struct nvm_dev *dev = rrpc->dev; 1155 1150 struct rrpc_lun *rlun; 1156 - int i, j; 1151 + int i, j, ret = -EINVAL; 1157 1152 1158 1153 if (dev->sec_per_blk > MAX_INVALID_PAGES_STORAGE * BITS_PER_LONG) { 1159 1154 pr_err("rrpc: number of pages per block too high."); ··· 1169 1164 1170 1165 /* 1:1 mapping */ 1171 1166 for (i = 0; i < rrpc->nr_luns; i++) { 1172 - struct nvm_lun *lun = dev->mt->get_lun(dev, lun_begin + i); 1167 + int lunid = lun_begin + i; 1168 + struct nvm_lun *lun; 1169 + 1170 + if (dev->mt->reserve_lun(dev, lunid)) { 1171 + pr_err("rrpc: lun %u is already allocated\n", lunid); 1172 + goto err; 1173 + } 1174 + 1175 + lun = dev->mt->get_lun(dev, lunid); 1176 + if (!lun) 1177 + goto err; 1173 1178 1174 1179 rlun = &rrpc->luns[i]; 1175 - rlun->rrpc = rrpc; 1176 1180 rlun->parent = lun; 1177 - INIT_LIST_HEAD(&rlun->prio_list); 1178 - INIT_LIST_HEAD(&rlun->open_list); 1179 - INIT_LIST_HEAD(&rlun->closed_list); 1180 - 1181 - INIT_WORK(&rlun->ws_gc, rrpc_lun_gc); 1182 - spin_lock_init(&rlun->lock); 1183 - 1184 - rrpc->total_blocks += dev->blks_per_lun; 1185 - rrpc->nr_sects += dev->sec_per_lun; 1186 - 1187 1181 rlun->blocks = vzalloc(sizeof(struct rrpc_block) * 1188 1182 rrpc->dev->blks_per_lun); 1189 - if (!rlun->blocks) 1183 + if (!rlun->blocks) { 1184 + ret = -ENOMEM; 1190 1185 goto err; 1186 + } 1191 1187 1192 1188 for (j = 0; j < rrpc->dev->blks_per_lun; j++) { 1193 1189 struct rrpc_block *rblk = &rlun->blocks[j]; ··· 1199 1193 INIT_LIST_HEAD(&rblk->prio); 1200 1194 spin_lock_init(&rblk->lock); 1201 1195 } 1196 + 1197 + rlun->rrpc = rrpc; 1198 + INIT_LIST_HEAD(&rlun->prio_list); 1199 + INIT_LIST_HEAD(&rlun->open_list); 1200 + INIT_LIST_HEAD(&rlun->closed_list); 1201 + 1202 + INIT_WORK(&rlun->ws_gc, rrpc_lun_gc); 1203 + spin_lock_init(&rlun->lock); 1204 + 1205 + rrpc->total_blocks += dev->blks_per_lun; 1206 + rrpc->nr_sects += dev->sec_per_lun; 1207 + 1202 1208 } 1203 1209 1204 1210 return 0; 1205 1211 err: 1206 - return -ENOMEM; 1212 + return ret; 1213 + } 1214 + 1215 + /* returns 0 on success and stores the beginning address in *begin */ 1216 + static int rrpc_area_init(struct rrpc *rrpc, sector_t *begin) 1217 + { 1218 + struct nvm_dev *dev = rrpc->dev; 1219 + struct nvmm_type *mt = dev->mt; 1220 + sector_t size = rrpc->nr_sects * dev->sec_size; 1221 + 1222 + size >>= 9; 1223 + 1224 + return mt->get_area(dev, begin, size); 1225 + } 1226 + 1227 + static void rrpc_area_free(struct rrpc *rrpc) 1228 + { 1229 + struct nvm_dev *dev = rrpc->dev; 1230 + struct nvmm_type *mt = dev->mt; 1231 + 1232 + mt->put_area(dev, rrpc->soffset); 1207 1233 } 1208 1234 1209 1235 static void rrpc_free(struct rrpc *rrpc) ··· 1244 1206 rrpc_map_free(rrpc); 1245 1207 rrpc_core_free(rrpc); 1246 1208 rrpc_luns_free(rrpc); 1209 + rrpc_area_free(rrpc); 1247 1210 1248 1211 kfree(rrpc); 1249 1212 } ··· 1366 1327 struct request_queue *bqueue = dev->q; 1367 1328 struct request_queue *tqueue = tdisk->queue; 1368 1329 struct rrpc *rrpc; 1330 + sector_t soffset; 1369 1331 int ret; 1370 1332 1371 1333 if (!(dev->identity.dom & NVM_RSP_L2P)) { ··· 1391 1351 1392 1352 /* simple round-robin strategy */ 1393 1353 atomic_set(&rrpc->next_lun, -1); 1354 + 1355 + ret = rrpc_area_init(rrpc, &soffset); 1356 + if (ret < 0) { 1357 + pr_err("nvm: rrpc: could not initialize area\n"); 1358 + return ERR_PTR(ret); 1359 + } 1360 + rrpc->soffset = soffset; 1394 1361 1395 1362 ret = rrpc_luns_init(rrpc, lun_begin, lun_end); 1396 1363 if (ret) {
+1
drivers/lightnvm/rrpc.h
··· 97 97 struct nvm_dev *dev; 98 98 struct gendisk *disk; 99 99 100 + sector_t soffset; /* logical sector offset */ 100 101 u64 poffset; /* physical page offset */ 101 102 int lun_offset; 102 103
+15 -2
drivers/nvme/host/lightnvm.c
··· 146 146 }; 147 147 }; 148 148 149 + struct nvme_nvm_completion { 150 + __le64 result; /* Used by LightNVM to return ppa completions */ 151 + __le16 sq_head; /* how much of this queue may be reclaimed */ 152 + __le16 sq_id; /* submission queue that generated this entry */ 153 + __u16 command_id; /* of the command which completed */ 154 + __le16 status; /* did the command fail, and if so, why? */ 155 + }; 156 + 149 157 #define NVME_NVM_LP_MLC_PAIRS 886 150 158 struct nvme_nvm_lp_mlc { 151 159 __u16 num_pairs; ··· 515 507 static void nvme_nvm_end_io(struct request *rq, int error) 516 508 { 517 509 struct nvm_rq *rqd = rq->end_io_data; 510 + struct nvme_nvm_completion *cqe = rq->special; 511 + 512 + if (cqe) 513 + rqd->ppa_status = le64_to_cpu(cqe->result); 518 514 519 515 nvm_end_io(rqd, error); 520 516 ··· 538 526 if (IS_ERR(rq)) 539 527 return -ENOMEM; 540 528 541 - cmd = kzalloc(sizeof(struct nvme_nvm_command), GFP_KERNEL); 529 + cmd = kzalloc(sizeof(struct nvme_nvm_command) + 530 + sizeof(struct nvme_nvm_completion), GFP_KERNEL); 542 531 if (!cmd) { 543 532 blk_mq_free_request(rq); 544 533 return -ENOMEM; ··· 558 545 559 546 rq->cmd = (unsigned char *)cmd; 560 547 rq->cmd_len = sizeof(struct nvme_nvm_command); 561 - rq->special = (void *)0; 548 + rq->special = cmd + 1; 562 549 563 550 rq->end_io_data = rqd; 564 551
+13 -11
drivers/nvme/host/pci.c
··· 723 723 blk_mq_end_request(req, error); 724 724 } 725 725 726 + /* We read the CQE phase first to check if the rest of the entry is valid */ 727 + static inline bool nvme_cqe_valid(struct nvme_queue *nvmeq, u16 head, 728 + u16 phase) 729 + { 730 + return (le16_to_cpu(nvmeq->cqes[head].status) & 1) == phase; 731 + } 732 + 726 733 static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag) 727 734 { 728 735 u16 head, phase; ··· 737 730 head = nvmeq->cq_head; 738 731 phase = nvmeq->cq_phase; 739 732 740 - for (;;) { 733 + while (nvme_cqe_valid(nvmeq, head, phase)) { 741 734 struct nvme_completion cqe = nvmeq->cqes[head]; 742 - u16 status = le16_to_cpu(cqe.status); 743 735 struct request *req; 744 736 745 - if ((status & 1) != phase) 746 - break; 747 737 if (++head == nvmeq->q_depth) { 748 738 head = 0; 749 739 phase = !phase; ··· 771 767 req = blk_mq_tag_to_rq(*nvmeq->tags, cqe.command_id); 772 768 if (req->cmd_type == REQ_TYPE_DRV_PRIV && req->special) 773 769 memcpy(req->special, &cqe, sizeof(cqe)); 774 - blk_mq_complete_request(req, status >> 1); 770 + blk_mq_complete_request(req, le16_to_cpu(cqe.status) >> 1); 775 771 776 772 } 777 773 ··· 812 808 static irqreturn_t nvme_irq_check(int irq, void *data) 813 809 { 814 810 struct nvme_queue *nvmeq = data; 815 - struct nvme_completion cqe = nvmeq->cqes[nvmeq->cq_head]; 816 - if ((le16_to_cpu(cqe.status) & 1) != nvmeq->cq_phase) 817 - return IRQ_NONE; 818 - return IRQ_WAKE_THREAD; 811 + if (nvme_cqe_valid(nvmeq, nvmeq->cq_head, nvmeq->cq_phase)) 812 + return IRQ_WAKE_THREAD; 813 + return IRQ_NONE; 819 814 } 820 815 821 816 static int nvme_poll(struct blk_mq_hw_ctx *hctx, unsigned int tag) 822 817 { 823 818 struct nvme_queue *nvmeq = hctx->driver_data; 824 819 825 - if ((le16_to_cpu(nvmeq->cqes[nvmeq->cq_head].status) & 1) == 826 - nvmeq->cq_phase) { 820 + if (nvme_cqe_valid(nvmeq, nvmeq->cq_head, nvmeq->cq_phase)) { 827 821 spin_lock_irq(&nvmeq->q_lock); 828 822 __nvme_process_cq(nvmeq, &tag); 829 823 spin_unlock_irq(&nvmeq->q_lock);
+24 -13
fs/fs-writeback.c
··· 281 281 wb_get(wb); 282 282 spin_unlock(&inode->i_lock); 283 283 spin_lock(&wb->list_lock); 284 - wb_put(wb); /* not gonna deref it anymore */ 285 284 286 285 /* i_wb may have changed inbetween, can't use inode_to_wb() */ 287 - if (likely(wb == inode->i_wb)) 288 - return wb; /* @inode already has ref */ 286 + if (likely(wb == inode->i_wb)) { 287 + wb_put(wb); /* @inode already has ref */ 288 + return wb; 289 + } 289 290 290 291 spin_unlock(&wb->list_lock); 292 + wb_put(wb); 291 293 cpu_relax(); 292 294 spin_lock(&inode->i_lock); 293 295 } ··· 1339 1337 * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode() 1340 1338 * and does more profound writeback list handling in writeback_sb_inodes(). 1341 1339 */ 1342 - static int 1343 - writeback_single_inode(struct inode *inode, struct bdi_writeback *wb, 1344 - struct writeback_control *wbc) 1340 + static int writeback_single_inode(struct inode *inode, 1341 + struct writeback_control *wbc) 1345 1342 { 1343 + struct bdi_writeback *wb; 1346 1344 int ret = 0; 1347 1345 1348 1346 spin_lock(&inode->i_lock); ··· 1380 1378 ret = __writeback_single_inode(inode, wbc); 1381 1379 1382 1380 wbc_detach_inode(wbc); 1383 - spin_lock(&wb->list_lock); 1381 + 1382 + wb = inode_to_wb_and_lock_list(inode); 1384 1383 spin_lock(&inode->i_lock); 1385 1384 /* 1386 1385 * If inode is clean, remove it from writeback lists. Otherwise don't ··· 1456 1453 1457 1454 while (!list_empty(&wb->b_io)) { 1458 1455 struct inode *inode = wb_inode(wb->b_io.prev); 1456 + struct bdi_writeback *tmp_wb; 1459 1457 1460 1458 if (inode->i_sb != sb) { 1461 1459 if (work->sb) { ··· 1547 1543 cond_resched(); 1548 1544 } 1549 1545 1550 - 1551 - spin_lock(&wb->list_lock); 1546 + /* 1547 + * Requeue @inode if still dirty. Be careful as @inode may 1548 + * have been switched to another wb in the meantime. 1549 + */ 1550 + tmp_wb = inode_to_wb_and_lock_list(inode); 1552 1551 spin_lock(&inode->i_lock); 1553 1552 if (!(inode->i_state & I_DIRTY_ALL)) 1554 1553 wrote++; 1555 - requeue_inode(inode, wb, &wbc); 1554 + requeue_inode(inode, tmp_wb, &wbc); 1556 1555 inode_sync_complete(inode); 1557 1556 spin_unlock(&inode->i_lock); 1557 + 1558 + if (unlikely(tmp_wb != wb)) { 1559 + spin_unlock(&tmp_wb->list_lock); 1560 + spin_lock(&wb->list_lock); 1561 + } 1558 1562 1559 1563 /* 1560 1564 * bail out to wb_writeback() often enough to check ··· 2350 2338 */ 2351 2339 int write_inode_now(struct inode *inode, int sync) 2352 2340 { 2353 - struct bdi_writeback *wb = &inode_to_bdi(inode)->wb; 2354 2341 struct writeback_control wbc = { 2355 2342 .nr_to_write = LONG_MAX, 2356 2343 .sync_mode = sync ? WB_SYNC_ALL : WB_SYNC_NONE, ··· 2361 2350 wbc.nr_to_write = 0; 2362 2351 2363 2352 might_sleep(); 2364 - return writeback_single_inode(inode, wb, &wbc); 2353 + return writeback_single_inode(inode, &wbc); 2365 2354 } 2366 2355 EXPORT_SYMBOL(write_inode_now); 2367 2356 ··· 2378 2367 */ 2379 2368 int sync_inode(struct inode *inode, struct writeback_control *wbc) 2380 2369 { 2381 - return writeback_single_inode(inode, &inode_to_bdi(inode)->wb, wbc); 2370 + return writeback_single_inode(inode, wbc); 2382 2371 } 2383 2372 EXPORT_SYMBOL(sync_inode); 2384 2373
-14
include/linux/blk-mq.h
··· 263 263 for ((i) = 0; (i) < (q)->nr_hw_queues && \ 264 264 ({ hctx = (q)->queue_hw_ctx[i]; 1; }); (i)++) 265 265 266 - #define queue_for_each_ctx(q, ctx, i) \ 267 - for ((i) = 0; (i) < (q)->nr_queues && \ 268 - ({ ctx = per_cpu_ptr((q)->queue_ctx, (i)); 1; }); (i)++) 269 - 270 266 #define hctx_for_each_ctx(hctx, ctx, i) \ 271 267 for ((i) = 0; (i) < (hctx)->nr_ctx && \ 272 268 ({ ctx = (hctx)->ctxs[(i)]; 1; }); (i)++) 273 - 274 - #define blk_ctx_sum(q, sum) \ 275 - ({ \ 276 - struct blk_mq_ctx *__x; \ 277 - unsigned int __ret = 0, __i; \ 278 - \ 279 - queue_for_each_ctx((q), __x, __i) \ 280 - __ret += sum; \ 281 - __ret; \ 282 - }) 283 269 284 270 #endif
+14
include/linux/lightnvm.h
··· 242 242 uint16_t nr_pages; 243 243 uint16_t flags; 244 244 245 + u64 ppa_status; /* ppa media status */ 245 246 int error; 246 247 }; 247 248 ··· 347 346 int nr_luns; 348 347 unsigned max_pages_per_blk; 349 348 349 + unsigned long *lun_map; 350 350 void *ppalist_pool; 351 351 352 352 struct nvm_id identity; ··· 357 355 char name[DISK_NAME_LEN]; 358 356 359 357 struct mutex mlock; 358 + spinlock_t lock; 360 359 }; 361 360 362 361 static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev, ··· 468 465 typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *, 469 466 unsigned long); 470 467 typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int); 468 + typedef int (nvmm_reserve_lun)(struct nvm_dev *, int); 469 + typedef void (nvmm_release_lun)(struct nvm_dev *, int); 471 470 typedef void (nvmm_lun_info_print_fn)(struct nvm_dev *); 471 + 472 + typedef int (nvmm_get_area_fn)(struct nvm_dev *, sector_t *, sector_t); 473 + typedef void (nvmm_put_area_fn)(struct nvm_dev *, sector_t); 472 474 473 475 struct nvmm_type { 474 476 const char *name; ··· 496 488 497 489 /* Configuration management */ 498 490 nvmm_get_lun_fn *get_lun; 491 + nvmm_reserve_lun *reserve_lun; 492 + nvmm_release_lun *release_lun; 499 493 500 494 /* Statistics */ 501 495 nvmm_lun_info_print_fn *lun_info_print; 496 + 497 + nvmm_get_area_fn *get_area; 498 + nvmm_put_area_fn *put_area; 499 + 502 500 struct list_head list; 503 501 }; 504 502