nvme: use __GFP_NOWARN for iod allocation
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
The iod can get quite large, requiring higher order allocations that we know can fail. Don't warn about them, as that just tends to flod the log with information we don't care about.
---
This begs the question is we should limit the size in general. The command overhead is low enough that I think we should default to something sane that doesn't require _any_ > 0 order allocations.
Our default 1280kb will require 10248 bytes of iod, which is an order 2 allocation.... That's not helping tail latencies in data centers, where memory is always full and fragmented.
drivers/nvme/host/pci.c +1 -1
@@ -480,7 +480,7 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev)size_t alloc_size =nvme_pci_iod_alloc_size (dev, size, nseg, iod->use_sgl); - iod->sg =kmalloc (alloc_size,GFP_ATOMIC ); + iod->sg =kmalloc (alloc_size,GFP_ATOMIC | __GFP_NOWARN);if (!iod->sg)return BLK_STS_RESOURCE ; }else {
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 7 lines · Jens Axboe
This begs the question is we should limit the size in general. The command overhead is low enough that I think we should default to something sane that doesn't require _any_ > 0 order allocations.
Our default 1280kb will require 10248 bytes of iod, which is an order 2 allocation.... That's not helping tail latencies in data centers, where memory is always full and fragmented.
In terms of sizing, defaulting to 256kb might not be a bad idea. That'd be 2056 bytes for a normal config. Alternatively we could go 1280/4 == 320k, which would be 2568 bytes.
In any case, I think it's something that's worth doing.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Jens Axboe
This begs the question is we should limit the size in general. The command overhead is low enough that I think we should default to something sane that doesn't require _any_ > 0 order allocations.
Our default 1280kb will require 10248 bytes of iod, which is an order 2 allocation.... That's not helping tail latencies in data centers, where memory is always full and fragmented.
Quoted 5 lines
In terms of sizing, defaulting to 256kb might not be a bad idea. That'd be 2056 bytes for a normal config. Alternatively we could go 1280/4 == 320k, which would be 2568 bytes.
In any case, I think it's something that's worth doing.
Talking more to myself - higher order allocations needed to make progress isn't a viable approach. There may _never_ be any available, which means we are stuck since this isn't backed by a mempool.
How about something like the below. Default to a size that will never require > PAGE_SIZE allocation, and back that with a single entry mempool. Even if we don't wait on it, if we keep retrying we'll always be able to allocate memory and make forward progress. And allocating a single page is a hell of a lot more likely than a 2nd order allocation.
drivers/nvme/host/core.c +7 -1
@@ -37,6 +37,12 @@#define NVME_MINORS (1U << MINORBITS) +/* +* This can be higher, but we need to ensure that any command doesn't +* require an iod->sg allocation that needs more than a page of aux data. +*/ +#define NVME_MAX_SECTORS 512 +unsigned int admin_timeout =60 ;module_param (admin_timeout, uint,0644 );MODULE_PARM_DESC (admin_timeout,"timeout in seconds for admin commands" );
@@ -2378,7 +2384,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)if (id->mdts) max_hw_sectors =1 << (id->mdts + page_shift -9 );else - max_hw_sectors =UINT_MAX ; + max_hw_sectors =NVME_MAX_SECTORS ; ctrl->max_hw_sectors =min_not_zero (ctrl->max_hw_sectors, max_hw_sectors);
drivers/nvme/host/pci.c +16 -5
@@ -100,6 +100,8 @@ struct nvme_dev {struct nvme_ctrl ctrl;struct completion ioq_wait; +mempool_t *iod_mempool; +/* shadow doorbell buffer support: */ u32 *dbbuf_dbs;dma_addr_t dbbuf_dbs_dma_addr;
@@ -477,10 +479,10 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) iod->use_sgl =nvme_pci_use_sgls (dev, rq);if (nseg >NVME_INT_PAGES || size >NVME_INT_BYTES (dev)) { -size_t alloc_size =nvme_pci_iod_alloc_size (dev, size, nseg, - iod->use_sgl); - - iod->sg =kmalloc (alloc_size,GFP_ATOMIC ); +BUG_ON (nvme_pci_iod_alloc_size (dev, size, +blk_rq_nr_phys_segments (rq), + iod->use_sgl) >PAGE_SIZE ); + iod->sg =mempool_alloc (dev->iod_mempool,GFP_ATOMIC );if (!iod->sg)return BLK_STS_RESOURCE ; }else {
@@ -526,7 +528,7 @@ static void nvme_free_iod(struct nvme_dev *dev, struct request *req) }if (iod->sg != iod->inline_sg) -kfree (iod->sg); +mempool_free (iod->sg, dev->iod_mempool); }#ifdef CONFIG_BLK_DEV_INTEGRITY
@@ -2280,6 +2282,7 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)blk_put_queue (dev->ctrl.admin_q);kfree (dev->queues);free_opal_dev (dev->ctrl.opal_dev); +mempool_destroy (dev->iod_mempool);kfree (dev); }
@@ -2546,6 +2549,14 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)if (result) goto release_pools; + dev->iod_mempool =mempool_create_node (1 , mempool_alloc_pages, + mempool_free_pages, (void *)0 , +GFP_ATOMIC , node); +if (!dev->iod_mempool) { + result = -ENOMEM ; + goto release_pools; + } +dev_info (dev->ctrl.device,"pci function %s\n" ,dev_name (&pdev->dev));nvme_get_ctrl (&dev->ctrl);
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 20 lines · Jens Axboe
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Jens Axboe
This begs the question is we should limit the size in general. The command overhead is low enough that I think we should default to something sane that doesn't require _any_ > 0 order allocations.
Our default 1280kb will require 10248 bytes of iod, which is an order 2 allocation.... That's not helping tail latencies in data centers, where memory is always full and fragmented.
Quoted 5 lines
In terms of sizing, defaulting to 256kb might not be a bad idea. That'd be 2056 bytes for a normal config. Alternatively we could go 1280/4 == 320k, which would be 2568 bytes.
In any case, I think it's something that's worth doing.
Talking more to myself - higher order allocations needed to make progress isn't a viable approach. There may _never_ be any available, which means we are stuck since this isn't backed by a mempool.
Quoted 6 lines
How about something like the below. Default to a size that will never require >
PAGE_SIZEallocation, and back that with a single entry mempool. Even if we don't wait on it, if we keep retrying we'll always be able to allocate memory and make forward progress. And allocating a single page is a hell of a lot more likely than a 2nd order allocation.
If we go this route, there is a great deal of cleanup that can follow on. For example, we'll never need to chain PRPs, so nvme_iod setup/free can become a lot simpler, and the struct iod npages and hidden "iod_list" member can go away.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 28 lines · Keith Busch
Quoted 20 lines · Jens Axboe
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Jens Axboe
This begs the question is we should limit the size in general. The command overhead is low enough that I think we should default to something sane that doesn't require _any_ > 0 order allocations.
Our default 1280kb will require 10248 bytes of iod, which is an order 2 allocation.... That's not helping tail latencies in data centers, where memory is always full and fragmented.
Quoted 5 lines
In terms of sizing, defaulting to 256kb might not be a bad idea. That'd be 2056 bytes for a normal config. Alternatively we could go 1280/4 == 320k, which would be 2568 bytes.
In any case, I think it's something that's worth doing.
Talking more to myself - higher order allocations needed to make progress isn't a viable approach. There may _never_ be any available, which means we are stuck since this isn't backed by a mempool.
Quoted 6 lines
How about something like the below. Default to a size that will never require >
PAGE_SIZEallocation, and back that with a single entry mempool. Even if we don't wait on it, if we keep retrying we'll always be able to allocate memory and make forward progress. And allocating a single page is a hell of a lot more likely than a 2nd order allocation.
Quoted 4 lines
If we go this route, there is a great deal of cleanup that can follow on. For example, we'll never need to chain PRPs, so
nvme_iodsetup/free can become a lot simpler, and the struct iod npages and hidden "iod_list" member can go away.
Missed this one before sending the other one out - yeah, I agree. And since we already have the inline sg for smaller commands, I think it makes a lot of sense to move in this direction.
I should also mention that this came out of a real life hang on a production box. I suppose we haven't seen a lot of these since a lot of nvme controllers have a hw limit of 128k, but the ones that don't can pretty easily hit the hang of needing 2^2 pages and failing miserably forever.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 5 lines · Jens Axboe
I should also mention that this came out of a real life hang on a production box. I suppose we haven't seen a lot of these since a lot of nvme controllers have a hw limit of 128k, but the ones that don't can pretty easily hit the hang of needing 2^2 pages and failing miserably forever.
I can certainly believe that. I'm totally fine with setting a smaller upper bound on the IO size. There really isn't a meaningful bandwidth advantage to larger transfers on NVMe PCIe once you get over 256k anyway.
Since you're making the change to core, let's wait to hear if there are any concerns on the fabrics front.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 10 lines · Keith Busch
Quoted 5 lines · Jens Axboe
I should also mention that this came out of a real life hang on a production box. I suppose we haven't seen a lot of these since a lot of nvme controllers have a hw limit of 128k, but the ones that don't can pretty easily hit the hang of needing 2^2 pages and failing miserably forever.
I can certainly believe that. I'm totally fine with setting a smaller upper bound on the IO size. There really isn't a meaningful bandwidth advantage to larger transfers on NVMe PCIe once you get over 256k anyway.
Right. We can retain most of the maximum size there, but the segments must go down. But functionally it's the same, and we're well within the region that should be plenty fast.
Quoted 2 lines
Since you're making the change to core, let's wait to hear if there are any concerns on the fabrics front.
If the fabrics folks have concerns, we could make it dependent on it being a pci device. That's the case I care about anyway, and the one that's currently breaking for me.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 3 lines · Jens Axboe
If the fabrics folks have concerns, we could make it dependent on it being a pci device. That's the case I care about anyway, and the one that's currently breaking for me.
Fabrics uses the SG chain allocator that SCSI also uses, so it should already be fine, including for larger I/O sizes.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 7 lines · Christoph Hellwig
Quoted 3 lines · Jens Axboe
If the fabrics folks have concerns, we could make it dependent on it being a pci device. That's the case I care about anyway, and the one that's currently breaking for me.
Fabrics uses the SG chain allocator that SCSI also uses, so it should already be fine, including for larger I/O sizes.
I'll change it to ignore it for fabrics. What's the best way to check? ctrl->sqsize?
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 11 lines · Jens Axboe
Quoted 7 lines · Christoph Hellwig
Quoted 3 lines · Jens Axboe
If the fabrics folks have concerns, we could make it dependent on it being a pci device. That's the case I care about anyway, and the one that's currently breaking for me.
Fabrics uses the SG chain allocator that SCSI also uses, so it should already be fine, including for larger I/O sizes.
I'll change it to ignore it for fabrics. What's the best way to check?
ctrl->sqsize?
ctrl->ops->flags & NVME_F_FABRICS
but in the end we probably want a separate flag, as that is an implementation detail, and not because these are fabrics drivers.
I'll be spending the rest of the day on phone calls, so it'll take some time to do more on this than writing some email, but I'll try to find some time to look into these issues.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 10 lines · Christoph Hellwig
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Christoph Hellwig
Quoted 3 lines · Jens Axboe
If the fabrics folks have concerns, we could make it dependent on it being a pci device. That's the case I care about anyway, and the one that's currently breaking for me.
Fabrics uses the SG chain allocator that SCSI also uses, so it should already be fine, including for larger I/O sizes.
Quoted 7 lines
Quoted 2 lines
I'll change it to ignore it for fabrics. What's the best way to check?
ctrl->sqsize?
ctrl->ops->flags&NVME_F_FABRICSbut in the end we probably want a separate flag, as that is an implementation detail, and not because these are fabrics drivers.
Probably fine for now with a comment, since it is pretty tightly coupled to the fact that we prefer larger commands on fabrics, and don't care so much about that for a local controller.
For now the check is moot though, since we are doing the same allocations...
Quoted 3 lines
I'll be spending the rest of the day on phone calls, so it'll take some time to do more on this than writing some email, but I'll try to find some time to look into these issues.
OK sounds good, would be nice to get this hashed out as I think some variant of this should go into 4.18.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 19 lines · Jens Axboe
Quoted 10 lines · Christoph Hellwig
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Christoph Hellwig
Quoted 3 lines · Jens Axboe
If the fabrics folks have concerns, we could make it dependent on it being a pci device. That's the case I care about anyway, and the one that's currently breaking for me.
Fabrics uses the SG chain allocator that SCSI also uses, so it should already be fine, including for larger I/O sizes.
Quoted 7 lines
Quoted 2 lines
I'll change it to ignore it for fabrics. What's the best way to check?
ctrl->sqsize?
ctrl->ops->flags&NVME_F_FABRICSbut in the end we probably want a separate flag, as that is an implementation detail, and not because these are fabrics drivers.
Quoted 6 lines
Probably fine for now with a comment, since it is pretty tightly coupled to the fact that we prefer larger commands on fabrics, and don't care so much about that for a local controller.
For now the check is moot though, since we are doing the same allocations...
For size I guess it's fine, as long as we limit segments. For reference, current version below.
drivers/nvme/host/core.c +5 -2
@@ -1808,8 +1808,9 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,u32 max_segments = (ctrl->max_hw_sectors / (ctrl->page_size >>9 )) +1 ; + max_segments =min_not_zero (max_segments, (u32 )NVME_MAX_SEGS );blk_queue_max_hw_sectors (q, ctrl->max_hw_sectors); -blk_queue_max_segments (q,min_t (u32, max_segments,USHRT_MAX )); +blk_queue_max_segments (q, max_segments); }if ((ctrl->quirks &NVME_QUIRK_STRIPE_SIZE ) &&is_power_of_2 (ctrl->max_hw_sectors))
@@ -2377,8 +2378,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) ctrl->cntlid =le16_to_cpup (&id->cntlid);if (id->mdts) max_hw_sectors =1 << (id->mdts + page_shift -9 ); -else +else if (ctrl->ops->flags &NVME_F_FABRICS ) max_hw_sectors =UINT_MAX ; +else + max_hw_sectors =NVME_MAX_KB_SZ <<1 ; ctrl->max_hw_sectors =min_not_zero (ctrl->max_hw_sectors, max_hw_sectors);
drivers/nvme/host/nvme.h +7 -0
@@ -33,6 +33,13 @@ extern unsigned int admin_timeout;#define NVME_DEFAULT_KATO 5#define NVME_KATO_GRACE 10 +/* +* These can be higher, but we need to ensure that any command doesn't +* require an sg allocation that needs more than a page of data. +*/ +#define NVME_MAX_KB_SZ 4096 +#define NVME_MAX_SEGS 127 +extern struct workqueue_struct *nvme_wq;extern struct workqueue_struct *nvme_reset_wq;extern struct workqueue_struct *nvme_delete_wq;
drivers/nvme/host/pci.c +18 -5
@@ -100,6 +100,8 @@ struct nvme_dev {struct nvme_ctrl ctrl;struct completion ioq_wait; +mempool_t *iod_mempool; +/* shadow doorbell buffer support: */ u32 *dbbuf_dbs;dma_addr_t dbbuf_dbs_dma_addr;
@@ -477,10 +479,7 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) iod->use_sgl =nvme_pci_use_sgls (dev, rq);if (nseg >NVME_INT_PAGES || size >NVME_INT_BYTES (dev)) { -size_t alloc_size =nvme_pci_iod_alloc_size (dev, size, nseg, - iod->use_sgl); - - iod->sg =kmalloc (alloc_size,GFP_ATOMIC ); + iod->sg =mempool_alloc (dev->iod_mempool,GFP_ATOMIC );if (!iod->sg)return BLK_STS_RESOURCE ; }else {
@@ -526,7 +525,7 @@ static void nvme_free_iod(struct nvme_dev *dev, struct request *req) }if (iod->sg != iod->inline_sg) -kfree (iod->sg); +mempool_free (iod->sg, dev->iod_mempool); }#ifdef CONFIG_BLK_DEV_INTEGRITY
@@ -2280,6 +2279,7 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)blk_put_queue (dev->ctrl.admin_q);kfree (dev->queues);free_opal_dev (dev->ctrl.opal_dev); +mempool_destroy (dev->iod_mempool);kfree (dev); }
@@ -2509,6 +2509,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)int node, result = -ENOMEM ;struct nvme_dev *dev;unsigned long quirks = id->driver_data; +size_t alloc_size; node =dev_to_node (&pdev->dev);if (node ==NUMA_NO_NODE )
@@ -2546,6 +2547,18 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)if (result) goto release_pools; + alloc_size =nvme_pci_iod_alloc_size (dev,NVME_MAX_KB_SZ , +NVME_MAX_SEGS , true); +WARN_ON_ONCE (alloc_size >PAGE_SIZE ); + dev->iod_mempool =mempool_create_node (1 , mempool_kmalloc, + mempool_kfree, + (void *) alloc_size, +GFP_KERNEL , node); +if (!dev->iod_mempool) { + result = -ENOMEM ; + goto release_pools; + } +dev_info (dev->ctrl.device,"pci function %s\n" ,dev_name (&pdev->dev));nvme_get_ctrl (&dev->ctrl);
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
I guess we can live with it for now with a big comment
drivers/nvme/host/core.c int nvme_init_identify(struct nvme_ctrl *ctrl) · line 2384
Quoted 8 lines
drivers/nvme/host/core.c +3
-1ctrl->cntlid =le16_to_cpup (&id->cntlid);if (id->mdts) max_hw_sectors =1 << (id->mdts + page_shift -9 ); -else +else if (ctrl->ops->flags &NVME_F_FABRICS ) max_hw_sectors =UINT_MAX ; +else + max_hw_sectors =NVME_MAX_KB_SZ <<1 ;
Can this I think is better done by setting ctrl->max_hw_sectors in the PCIe driver (similar to what the other drivers already do) and then rely on the min_not_zero below to factor in MDTS.
drivers/nvme/host/nvme.h extern unsigned int admin_timeout; · line 40
Quoted 5 lines
drivers/nvme/host/nvme.h +5
-0+/* +* These can be higher, but we need to ensure that any command doesn't +* require an sg allocation that needs more than a page of data. +*/ +#define NVME_MAX_KB_SZ 4096
I think this should move the pci.c
Quoted 1 line
+#define
NVME_MAX_SEGS127
And this could use a good explanation. Especially as I think that we shouldn't apply the limit for fabrics. So instead we might just add a new ctrl->max_segments field, which PCI sets, and which then is min() with the otherwise calculated value.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 14 lines · Christoph Hellwig
I guess we can live with it for now with a big comment
drivers/nvme/host/core.c int nvme_init_identify(struct nvme_ctrl *ctrl) · line 2384
Quoted 8 lines
drivers/nvme/host/core.c +3
-1ctrl->cntlid =le16_to_cpup (&id->cntlid);if (id->mdts) max_hw_sectors =1 << (id->mdts + page_shift -9 ); -else +else if (ctrl->ops->flags &NVME_F_FABRICS ) max_hw_sectors =UINT_MAX ; +else + max_hw_sectors =NVME_MAX_KB_SZ <<1 ;Can this I think is better done by setting
ctrl->max_hw_sectorsin the PCIe driver (similar to what the other drivers already do) and then rely on themin_not_zerobelow to factor in MDTS.
Yeah, I can put it there, and we can get rid of the check here. Maybe do the same for segments, adding a ctrl->max_segments. If non-zero, use that in init_ctrl().
Quoted 7 lines
drivers/nvme/host/nvme.h extern unsigned int admin_timeout; · line 40
Quoted 5 lines
drivers/nvme/host/nvme.h +5
-0+/* +* These can be higher, but we need to ensure that any command doesn't +* require an sg allocation that needs more than a page of data. +*/ +#define NVME_MAX_KB_SZ 4096I think this should move the
pci.c
With the above change it can.
Quoted 6 lines
Quoted 1 line
+#define
NVME_MAX_SEGS127And this could use a good explanation. Especially as I think that we shouldn't apply the limit for fabrics. So instead we might just add a new
ctrl->max_segmentsfield, which PCI sets, and which then ismin()with the otherwise calculated value.
I'll add that.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
In reply to Jens AxboeQuoted 6 lines · Jens Axboe
Quoted 3 lines
I'll be spending the rest of the day on phone calls, so it'll take some time to do more on this than writing some email, but I'll try to find some time to look into these issues.
OK sounds good, would be nice to get this hashed out as I think some variant of this should go into 4.18.
Fine with me, but I'd rather not rush it out this week to give us a little more time for details and aim for merging it to 4.18 next week.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 11 lines · Christoph Hellwig
Quoted 6 lines · Jens Axboe
Quoted 3 lines
I'll be spending the rest of the day on phone calls, so it'll take some time to do more on this than writing some email, but I'll try to find some time to look into these issues.
OK sounds good, would be nice to get this hashed out as I think some variant of this should go into 4.18.
Fine with me, but I'd rather not rush it out this week to give us a little more time for details and aim for merging it to 4.18 next week.
Oh, I'm totally fine with that, no rush outside of just wanting to ensure it ends up in 4.18. But there's plenty of time for that.
Below is cleaner I think, keeping it all in pci.c and fabrics should just work. I'll test...
drivers/nvme/host/core.c +1 -0
@@ -1808,6 +1808,7 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,u32 max_segments = (ctrl->max_hw_sectors / (ctrl->page_size >>9 )) +1 ; + max_segments =min_not_zero (max_segments, ctrl->max_segments);blk_queue_max_hw_sectors (q, ctrl->max_hw_sectors);blk_queue_max_segments (q,min_t (u32, max_segments,USHRT_MAX )); }
drivers/nvme/host/nvme.h +1 -0
@@ -170,6 +170,7 @@ struct nvme_ctrl {u64 cap;u32 page_size;u32 max_hw_sectors; +u32 max_segments;u16 oncs;u16 oacs;u16 nssa;
drivers/nvme/host/pci.c +37 -5
90 lines not on this page · raw message
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 5 lines · Jens Axboe
Oh, I'm totally fine with that, no rush outside of just wanting to ensure it ends up in 4.18. But there's plenty of time for that.
Below is cleaner I think, keeping it all in
pci.cand fabrics should just work. I'll test...
Ok, this actually looks harmless enough that with successfull testing and an ack from Keith we could queue it up this week..
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 9 lines · Christoph Hellwig
Quoted 5 lines · Jens Axboe
Oh, I'm totally fine with that, no rush outside of just wanting to ensure it ends up in 4.18. But there's plenty of time for that.
Below is cleaner I think, keeping it all in
pci.cand fabrics should just work. I'll test...Ok, this actually looks harmless enough that with successfull testing and an ack from Keith we could queue it up this week..
Tested it here now (laptop and box with 6 drives), works for me. Proper patch below.
From: Jens Axboe <[email protected]>
Subject: [PATCH] nvme: limit max IO size and segments for pci-e
nvme requires an sg table allocation for each request. If the request is large, then the allocation can become quite large. For instance, with our default software settings of 1280KB IO size, we'll need 10248 bytes of sg table. That turns into a 2nd order allocation, which we can't always guarantee. If we fail the allocation, blk-mq will retry it later. But there's no guarantee that we'll EVER be able to allocate that much contigious memory.
Limit the IO size such that we never need more than a single page of memory. That's a lot faster and more reliable. Then back that allocation with a mempool, so that we know we'll always be able to succeed the allocation at some point.
drivers/nvme/host/core.c +1 -0
@@ -1808,6 +1808,7 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,u32 max_segments = (ctrl->max_hw_sectors / (ctrl->page_size >>9 )) +1 ; + max_segments =min_not_zero (max_segments, ctrl->max_segments);blk_queue_max_hw_sectors (q, ctrl->max_hw_sectors);blk_queue_max_segments (q,min_t (u32, max_segments,USHRT_MAX )); }
drivers/nvme/host/nvme.h +1 -0
@@ -170,6 +170,7 @@ struct nvme_ctrl {u64 cap;u32 page_size;u32 max_hw_sectors; +u32 max_segments;u16 oncs;u16 oacs;u16 nssa;
drivers/nvme/host/pci.c +37 -5
90 lines not on this page · raw message
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 11 lines · Jens Axboe
From: Jens Axboe <axboe at kernel.dk>
Subject: [PATCH] nvme: limit max IO size and segments for pci-envme requires an sg table allocation for each request. If the request is large, then the allocation can become quite large. For instance, with our default software settings of 1280KB IO size, we'll need 10248 bytes of sg table. That turns into a 2nd order allocation, which we can't always guarantee. If we fail the allocation, blk-mq will retry it later. But there's no guarantee that we'll EVER be able to allocate that much contigious memory.
Quoted 6 lines
Limit the IO size such that we never need more than a single page of memory. That's a lot faster and more reliable. Then back that allocation with a mempool, so that we know we'll always be able to succeed the allocation at some point.
Signed-off-by Jens Axboe <axboe at kernel.dk>
This looks good to me. Thanks!
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 17 lines · Keith Busch
Quoted 16 lines · Jens Axboe
From: Jens Axboe <axboe at kernel.dk>
Subject: [PATCH] nvme: limit max IO size and segments for pci-envme requires an sg table allocation for each request. If the request is large, then the allocation can become quite large. For instance, with our default software settings of 1280KB IO size, we'll need 10248 bytes of sg table. That turns into a 2nd order allocation, which we can't always guarantee. If we fail the allocation, blk-mq will retry it later. But there's no guarantee that we'll EVER be able to allocate that much contigious memory.
Limit the IO size such that we never need more than a single page of memory. That's a lot faster and more reliable. Then back that allocation with a mempool, so that we know we'll always be able to succeed the allocation at some point.
Quoted 5 lines
Quoted 1 line
Signed-off-by Jens Axboe <axboe at kernel.dk>This looks good to me. Thanks!
Acked-by Keith Busch <keith.busch at intel.com>
Thanks Keith - Christoph/Keith, where do you want to queue this up? I can do it directly, or we can do it through the nvme tree.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 2 lines · Jens Axboe
Thanks Keith - Christoph/Keith, where do you want to queue this up? I can do it directly, or we can do it through the nvme tree.
I've queued it up in the nvme tree already.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 5 lines · Christoph Hellwig
Quoted 2 lines · Jens Axboe
Thanks Keith - Christoph/Keith, where do you want to queue this up? I can do it directly, or we can do it through the nvme tree.
I've queued it up in the nvme tree already.
Perfect, thanks.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
In reply to Jens AxboeQuoted 20 lines · Jens Axboe
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Jens Axboe
This begs the question is we should limit the size in general. The command overhead is low enough that I think we should default to something sane that doesn't require _any_ > 0 order allocations.
Our default 1280kb will require 10248 bytes of iod, which is an order 2 allocation.... That's not helping tail latencies in data centers, where memory is always full and fragmented.
Quoted 5 lines
In terms of sizing, defaulting to 256kb might not be a bad idea. That'd be 2056 bytes for a normal config. Alternatively we could go 1280/4 == 320k, which would be 2568 bytes.
In any case, I think it's something that's worth doing.
Talking more to myself - higher order allocations needed to make progress isn't a viable approach. There may _never_ be any available, which means we are stuck since this isn't backed by a mempool.
Quoted 6 lines
How about something like the below. Default to a size that will never require >
PAGE_SIZEallocation, and back that with a single entry mempool. Even if we don't wait on it, if we keep retrying we'll always be able to allocate memory and make forward progress. And allocating a single page is a hell of a lot more likely than a 2nd order allocation.
This one is actually tested. As a nice benefit, the pool is node local and we take the divisions out of the fast path since we no longer need to calculate the iod->sg size.
drivers/nvme/host/core.c +3 -2
@@ -1808,8 +1808,9 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,u32 max_segments = (ctrl->max_hw_sectors / (ctrl->page_size >>9 )) +1 ; + max_segments =min_not_zero (max_segments, (u32 )NVME_MAX_SEGS );blk_queue_max_hw_sectors (q, ctrl->max_hw_sectors); -blk_queue_max_segments (q,min_t (u32, max_segments,USHRT_MAX )); +blk_queue_max_segments (q, max_segments); }if ((ctrl->quirks &NVME_QUIRK_STRIPE_SIZE ) &&is_power_of_2 (ctrl->max_hw_sectors))
@@ -2378,7 +2379,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)if (id->mdts) max_hw_sectors =1 << (id->mdts + page_shift -9 );else - max_hw_sectors =UINT_MAX ; + max_hw_sectors =NVME_MAX_KB_SZ <<1 ; ctrl->max_hw_sectors =min_not_zero (ctrl->max_hw_sectors, max_hw_sectors);
drivers/nvme/host/nvme.h +7 -0
@@ -33,6 +33,13 @@ extern unsigned int admin_timeout;#define NVME_DEFAULT_KATO 5#define NVME_KATO_GRACE 10 +/* +* These can be higher, but we need to ensure that any command doesn't +* require an sg allocation that needs more than a page of data. +*/ +#define NVME_MAX_KB_SZ 4096 +#define NVME_MAX_SEGS 127 +extern struct workqueue_struct *nvme_wq;extern struct workqueue_struct *nvme_reset_wq;extern struct workqueue_struct *nvme_delete_wq;
drivers/nvme/host/pci.c +18 -5
@@ -100,6 +100,8 @@ struct nvme_dev {struct nvme_ctrl ctrl;struct completion ioq_wait; +mempool_t *iod_mempool; +/* shadow doorbell buffer support: */ u32 *dbbuf_dbs;dma_addr_t dbbuf_dbs_dma_addr;
@@ -477,10 +479,7 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) iod->use_sgl =nvme_pci_use_sgls (dev, rq);if (nseg >NVME_INT_PAGES || size >NVME_INT_BYTES (dev)) { -size_t alloc_size =nvme_pci_iod_alloc_size (dev, size, nseg, - iod->use_sgl); - - iod->sg =kmalloc (alloc_size,GFP_ATOMIC ); + iod->sg =mempool_alloc (dev->iod_mempool,GFP_ATOMIC );if (!iod->sg)return BLK_STS_RESOURCE ; }else {
@@ -526,7 +525,7 @@ static void nvme_free_iod(struct nvme_dev *dev, struct request *req) }if (iod->sg != iod->inline_sg) -kfree (iod->sg); +mempool_free (iod->sg, dev->iod_mempool); }#ifdef CONFIG_BLK_DEV_INTEGRITY
@@ -2280,6 +2279,7 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)blk_put_queue (dev->ctrl.admin_q);kfree (dev->queues);free_opal_dev (dev->ctrl.opal_dev); +mempool_destroy (dev->iod_mempool);kfree (dev); }
@@ -2509,6 +2509,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)int node, result = -ENOMEM ;struct nvme_dev *dev;unsigned long quirks = id->driver_data; +size_t alloc_size; node =dev_to_node (&pdev->dev);if (node ==NUMA_NO_NODE )
@@ -2546,6 +2547,18 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)if (result) goto release_pools; + alloc_size =nvme_pci_iod_alloc_size (dev,NVME_MAX_KB_SZ , +NVME_MAX_SEGS , true); +WARN_ON_ONCE (alloc_size >PAGE_SIZE ); + dev->iod_mempool =mempool_create_node (1 , mempool_kmalloc, + mempool_kfree, + (void *) alloc_size, +GFP_KERNEL , node); +if (!dev->iod_mempool) { + result = -ENOMEM ; + goto release_pools; + } +dev_info (dev->ctrl.device,"pci function %s\n" ,dev_name (&pdev->dev));nvme_get_ctrl (&dev->ctrl);
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
drivers/nvme/host/core.c int nvme_init_identify(struct nvme_ctrl *ctrl) · line 2382
Quoted 3 lines
drivers/nvme/host/core.c +1
-1else - max_hw_sectors =UINT_MAX ; + max_hw_sectors =NVME_MAX_KB_SZ <<1 ;
I think this only makes sense when using PRPs. If we use SGLs in Fabrics, or in PCIe controllers that support them we are only bound by the number of SGL segments and MDTS.
This also seems to miss handling the case where MDTS is set, but above our software limit.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 7 lines · Christoph Hellwig
drivers/nvme/host/core.c int nvme_init_identify(struct nvme_ctrl *ctrl) · line 2382
Quoted 3 lines
drivers/nvme/host/core.c +1
-1else - max_hw_sectors =UINT_MAX ; + max_hw_sectors =NVME_MAX_KB_SZ <<1 ;I think this only makes sense when using PRPs. If we use SGLs in Fabrics, or in PCIe controllers that support them we are only bound by the number of SGL segments and MDTS.
The problem is that we have to limit the max size, since the sg allocation depends on that, marginally. In reality, the segments will dictate the max size anyway.
Quoted 2 lines
This also seems to miss handling the case where MDTS is set, but above our software limit.
Shouldn't, we're using the min of MDTS and the software limit.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Christoph Hellwig
drivers/nvme/host/core.c int nvme_init_identify(struct nvme_ctrl *ctrl) · line 2382
Quoted 3 lines
drivers/nvme/host/core.c +1
-1else - max_hw_sectors =UINT_MAX ; + max_hw_sectors =NVME_MAX_KB_SZ <<1 ;I think this only makes sense when using PRPs. If we use SGLs in Fabrics, or in PCIe controllers that support them we are only bound by the number of SGL segments and MDTS.
Quoted 3 lines
The problem is that we have to limit the max size, since the sg allocation depends on that, marginally. In reality, the segments will dictate the max size anyway.
The sg allocation depends on the number of segments. The PRP allocation (if using PRPs) depends purely on the size + a little slack for unaligned first or last arguments.
Quoted 5 lines
Quoted 3 lines
This also seems to miss handling the case where MDTS is set, but above our software limit.
Shouldn't, we're using the min of MDTS and the software limit.
Ok, maybe I misread the patch, but it surely looked like that.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 10 lines · Christoph Hellwig
Quoted 9 lines · Jens Axboe
Quoted 7 lines · Christoph Hellwig
drivers/nvme/host/core.c int nvme_init_identify(struct nvme_ctrl *ctrl) · line 2382
Quoted 3 lines
drivers/nvme/host/core.c +1
-1else - max_hw_sectors =UINT_MAX ; + max_hw_sectors =NVME_MAX_KB_SZ <<1 ;I think this only makes sense when using PRPs. If we use SGLs in Fabrics, or in PCIe controllers that support them we are only bound by the number of SGL segments and MDTS.
Quoted 7 lines
Quoted 3 lines
The problem is that we have to limit the max size, since the sg allocation depends on that, marginally. In reality, the segments will dictate the max size anyway.
The sg allocation depends on the number of segments. The PRP allocation (if using PRPs) depends purely on the size + a little slack for unaligned first or last arguments.
Right. So for sg, we can ignore the size, and just limit the segments.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
In reply to Jens AxboeQuoted 3 lines · Jens Axboe
Talking more to myself - higher order allocations needed to make progress isn't a viable approach. There may _never_ be any available, which means we are stuck since this isn't backed by a mempool.
Yes, I've complained about that a few times in the past, but so far no one has hit it in practice.
Quoted 6 lines
How about something like the below. Default to a size that will never require >
PAGE_SIZEallocation, and back that with a single entry mempool. Even if we don't wait on it, if we keep retrying we'll always be able to allocate memory and make forward progress. And allocating a single page is a hell of a lot more likely than a 2nd order allocation.
I suspect some people might be unhappy about the limit on I/O sizes. That is why we want through all that effort with chained S/G lists in SCSI, which are now also used by NVMe over Fabrics. But except for that we absolutely have to move to mempools.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 7 lines · Christoph Hellwig
Quoted 3 lines · Jens Axboe
Talking more to myself - higher order allocations needed to make progress isn't a viable approach. There may _never_ be any available, which means we are stuck since this isn't backed by a mempool.
Yes, I've complained about that a few times in the past, but so far no one has hit it in practice.
Well, I have :-). The problem is that it'll only really happen in production, since no micro testing will end up with memory fragmented enough to pose an issue.
Quoted 7 lines
Quoted 6 lines
How about something like the below. Default to a size that will never require >
PAGE_SIZEallocation, and back that with a single entry mempool. Even if we don't wait on it, if we keep retrying we'll always be able to allocate memory and make forward progress. And allocating a single page is a hell of a lot more likely than a 2nd order allocation.
Quoted 5 lines
I suspect some people might be unhappy about the limit on I/O sizes. That is why we want through all that effort with chained S/G lists in SCSI, which are now also used by NVMe over Fabrics. But except for that we absolutely have to move to mempools.
That may be the case, but it's a lot less of an issue than SCSI is, since the command overhead is suitably small. So I don't see a big issue with limiting it. Besides, having to do higher order allocations for an IO is bound to pose much bigger issues than having two smaller IOs instead. That's especially true in production, where memory allocation stalls are pretty frequent.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 3 lines · Jens Axboe
That may be the case, but it's a lot less of an issue than SCSI is, since the command overhead is suitably small. So I don't see a big issue with limiting it.
Not if you are using NVMe over FC, which uses exactly the same protocol to transfer a 64 byte NVMe SQ vs a typically 16 byte SCSI CDB..
Quoted 4 lines
Besides, having to do higher order allocations for an
IO is bound to pose much bigger issues than having two smaller IOs instead. That's especially true in production, where memory allocation stalls are pretty frequent.
But the whole point of our chained sg allocator is that we don't do high order allocations, but multiple smaller ones and then chain them.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 8 lines · Christoph Hellwig
Quoted 3 lines · Jens Axboe
That may be the case, but it's a lot less of an issue than SCSI is, since the command overhead is suitably small. So I don't see a big issue with limiting it.
Not if you are using NVMe over FC, which uses exactly the same protocol to transfer a 64 byte NVMe SQ vs a typically 16 byte SCSI CDB..
I should have prefaced that with saying "for pci-e". For fabrics, I agree.
Quoted 11 lines
Quoted 4 lines
Besides, having to do higher order allocations for an
IO is bound to pose much bigger issues than having two smaller IOs instead. That's especially true in production, where memory allocation stalls are pretty frequent.But the whole point of our chained sg allocator is that we don't do high order allocations, but multiple smaller ones and then chain them.
From a quick look, the fabric code goes through the same
nvme_queue_rq()
and ends up doing the same iod->sg allocation. I don't see any use of chained sg lists, we're allocating one big sg table for the command.
Signature · 1 line
Jens Axboe
PATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 3 lines · Jens Axboe
Quoted 1 line
From a quick look, the fabric code goes through the same
nvme_queue_rq()and ends up doing the same
iod->sgallocation. I don't see any use of chained sg lists, we're allocating one big sg table for the command.
nvme_queue_rq is only used for PCIe.
E.g. for RDMA the call is:
nvme_rdma_queue_rq
-> nvme_rdma_map_data
-> sg_alloc_table_chained
similar for FC and loop.
Jens Axboe
maintainerPATCH 1/1 nvme: use __GFP_NOWARN for iod allocation
Quoted 7 lines · Christoph Hellwig
Quoted 3 lines · Jens Axboe
Quoted 1 line
From a quick look, the fabric code goes through the same
nvme_queue_rq()and ends up doing the same
iod->sgallocation. I don't see any use of chained sg lists, we're allocating one big sg table for the command.
nvme_queue_rqis only used for PCIe.
Quoted 7 lines
E.g. for RDMA the call is:
nvme_rdma_queue_rq
->nvme_rdma_map_data
->sg_alloc_table_chainedsimilar for FC and loop.
Gotcha. So we can safely ignore limiting segments and max size for fabrics for now.
How about the below?
drivers/nvme/host/core.c +17 -2
@@ -1799,6 +1799,16 @@ int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl) }EXPORT_SYMBOL_GPL (nvme_shutdown_ctrl); +/* +* For non-fabrics, limit the max IO size and segments so that we know our +* iod->sg allocation can fall within a single page. Fabrics is more sensitive +* to command size, and it also does sg chaining to avoid large allocations. +*/ +static bool nvme_ctrl_limit_io_size (struct nvme_ctrl *ctrl) +{ +return (ctrl->ops->flags &NVME_F_FABRICS ) ==0 ; +} +static void nvme_set_queue_limits (struct nvme_ctrl *ctrl,struct request_queue *q) {
@@ -1808,8 +1818,11 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,u32 max_segments = (ctrl->max_hw_sectors / (ctrl->page_size >>9 )) +1 ; +if (nvme_ctrl_limit_io_size (ctrl)) + max_segments =min_not_zero (max_segments, + (u32 )NVME_MAX_SEGS );blk_queue_max_hw_sectors (q, ctrl->max_hw_sectors); -blk_queue_max_segments (q,min_t (u32, max_segments,USHRT_MAX )); +blk_queue_max_segments (q, max_segments); }if ((ctrl->quirks &NVME_QUIRK_STRIPE_SIZE ) &&is_power_of_2 (ctrl->max_hw_sectors))
@@ -2377,8 +2390,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) ctrl->cntlid =le16_to_cpup (&id->cntlid);if (id->mdts) max_hw_sectors =1 << (id->mdts + page_shift -9 ); -else +else if (!nvme_ctrl_limit_io_size (ctrl)) max_hw_sectors =UINT_MAX ; +else + max_hw_sectors =NVME_MAX_KB_SZ <<1 ; ctrl->max_hw_sectors =min_not_zero (ctrl->max_hw_sectors, max_hw_sectors);
drivers/nvme/host/nvme.h +7 -0
@@ -33,6 +33,13 @@ extern unsigned int admin_timeout;#define NVME_DEFAULT_KATO 5#define NVME_KATO_GRACE 10 +/* +* These can be higher, but we need to ensure that any command doesn't +* require an sg allocation that needs more than a page of data. +*/ +#define NVME_MAX_KB_SZ 4096 +#define NVME_MAX_SEGS 127 +extern struct workqueue_struct *nvme_wq;extern struct workqueue_struct *nvme_reset_wq;extern struct workqueue_struct *nvme_delete_wq;
drivers/nvme/host/pci.c +23 -5
@@ -100,6 +100,8 @@ struct nvme_dev {struct nvme_ctrl ctrl;struct completion ioq_wait; +mempool_t *iod_mempool; +/* shadow doorbell buffer support: */ u32 *dbbuf_dbs;dma_addr_t dbbuf_dbs_dma_addr;
@@ -477,10 +479,7 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev) iod->use_sgl =nvme_pci_use_sgls (dev, rq);if (nseg >NVME_INT_PAGES || size >NVME_INT_BYTES (dev)) { -size_t alloc_size =nvme_pci_iod_alloc_size (dev, size, nseg, - iod->use_sgl); - - iod->sg =kmalloc (alloc_size,GFP_ATOMIC ); + iod->sg =mempool_alloc (dev->iod_mempool,GFP_ATOMIC );if (!iod->sg)return BLK_STS_RESOURCE ; }else {
@@ -526,7 +525,7 @@ static void nvme_free_iod(struct nvme_dev *dev, struct request *req) }if (iod->sg != iod->inline_sg) -kfree (iod->sg); +mempool_free (iod->sg, dev->iod_mempool); }#ifdef CONFIG_BLK_DEV_INTEGRITY
@@ -2280,6 +2279,7 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)blk_put_queue (dev->ctrl.admin_q);kfree (dev->queues);free_opal_dev (dev->ctrl.opal_dev); +mempool_destroy (dev->iod_mempool);kfree (dev); }
@@ -2509,6 +2509,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)int node, result = -ENOMEM ;struct nvme_dev *dev;unsigned long quirks = id->driver_data; +size_t alloc_size; node =dev_to_node (&pdev->dev);if (node ==NUMA_NO_NODE )
@@ -2546,6 +2547,23 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)if (result) goto release_pools; +/* +* Double check that our mempool alloc size will cover the biggest +* command we support. +*/ + alloc_size =nvme_pci_iod_alloc_size (dev,NVME_MAX_KB_SZ , +NVME_MAX_SEGS , true); +WARN_ON_ONCE (alloc_size >PAGE_SIZE ); + + dev->iod_mempool =mempool_create_node (1 , mempool_kmalloc, + mempool_kfree, + (void *) alloc_size, +GFP_KERNEL , node); +if (!dev->iod_mempool) { + result = -ENOMEM ; + goto release_pools; + } +dev_info (dev->ctrl.device,"pci function %s\n" ,dev_name (&pdev->dev));nvme_get_ctrl (&dev->ctrl);
Signature · 1 line
Jens Axboe