Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 286259
b: refs/heads/master
c: 99802a7
h: refs/heads/master
i:
  286257: 9a8a2e7
  286255: 15c7efc
v: v3
  • Loading branch information
Matthew Wilcox committed Nov 4, 2011
1 parent 9be6e87 commit f878ddb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 091b609258b8e01cc45b01a41ca5e496f674d989
refs/heads/master: 99802a7aee2b3dd720e382c52b892cc6a8122b11
31 changes: 23 additions & 8 deletions trunk/drivers/block/nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct nvme_dev {
u32 __iomem *dbs;
struct pci_dev *pci_dev;
struct dma_pool *prp_page_pool;
struct dma_pool *prp_small_pool;
int instance;
int queue_count;
u32 ctrl_config;
Expand Down Expand Up @@ -249,11 +250,6 @@ static int nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd)
return 0;
}

static __le64 *alloc_prp_list(struct nvme_dev *dev, dma_addr_t *addr)
{
return dma_pool_alloc(dev->prp_page_pool, GFP_ATOMIC, addr);
}

struct nvme_prps {
int npages;
dma_addr_t first_dma;
Expand All @@ -271,6 +267,9 @@ static void nvme_free_prps(struct nvme_queue *nvmeq, struct nvme_prps *prps)
return;

prp_dma = prps->first_dma;

if (prps->npages == 0)
dma_pool_free(dev->prp_small_pool, prps->list[0], prp_dma);
for (i = 0; i < prps->npages; i++) {
__le64 *prp_list = prps->list[i];
dma_addr_t next_prp_dma = le64_to_cpu(prp_list[last_prp]);
Expand Down Expand Up @@ -322,6 +321,7 @@ static struct nvme_prps *nvme_setup_prps(struct nvme_queue *nvmeq,
struct scatterlist *sg, int length)
{
struct nvme_dev *dev = nvmeq->dev;
struct dma_pool *pool;
int dma_len = sg_dma_len(sg);
u64 dma_addr = sg_dma_address(sg);
int offset = offset_in_page(dma_addr);
Expand Down Expand Up @@ -352,17 +352,24 @@ static struct nvme_prps *nvme_setup_prps(struct nvme_queue *nvmeq,
nprps = DIV_ROUND_UP(length, PAGE_SIZE);
npages = DIV_ROUND_UP(8 * nprps, PAGE_SIZE);
prps = kmalloc(sizeof(*prps) + sizeof(__le64 *) * npages, GFP_ATOMIC);
prps->npages = npages;
prp_page = 0;
prp_list = alloc_prp_list(dev, &prp_dma);
if (nprps <= (256 / 8)) {
pool = dev->prp_small_pool;
prps->npages = 0;
} else {
pool = dev->prp_page_pool;
prps->npages = npages;
}

prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
prps->list[prp_page++] = prp_list;
prps->first_dma = prp_dma;
cmd->prp2 = cpu_to_le64(prp_dma);
i = 0;
for (;;) {
if (i == PAGE_SIZE / 8 - 1) {
__le64 *old_prp_list = prp_list;
prp_list = alloc_prp_list(dev, &prp_dma);
prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
prps->list[prp_page++] = prp_list;
old_prp_list[i] = cpu_to_le64(prp_dma);
i = 0;
Expand Down Expand Up @@ -1313,12 +1320,20 @@ static int nvme_setup_prp_pools(struct nvme_dev *dev)
if (!dev->prp_page_pool)
return -ENOMEM;

/* Optimisation for I/Os between 4k and 128k */
dev->prp_small_pool = dma_pool_create("prp list 256", dmadev,
256, 256, 0);
if (!dev->prp_small_pool) {
dma_pool_destroy(dev->prp_page_pool);
return -ENOMEM;
}
return 0;
}

static void nvme_release_prp_pools(struct nvme_dev *dev)
{
dma_pool_destroy(dev->prp_page_pool);
dma_pool_destroy(dev->prp_small_pool);
}

/* XXX: Use an ida or something to let remove / add work correctly */
Expand Down

0 comments on commit f878ddb

Please sign in to comment.