diff options
author | Anup Patel <anup.patel@broadcom.com> | 2017-08-22 11:56:56 +0200 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2017-08-28 13:14:24 +0200 |
commit | 5655e00f5cde2c856c80eb10d0e6c911b7d880f2 (patch) | |
tree | adc764a18c7955eb664e12a2aef903f9dcdbb0a0 /drivers/dma | |
parent | dmaengine: bcm-sba-raid: Remove reqs_free_count from sba_device (diff) | |
download | linux-5655e00f5cde2c856c80eb10d0e6c911b7d880f2.tar.xz linux-5655e00f5cde2c856c80eb10d0e6c911b7d880f2.zip |
dmaengine: bcm-sba-raid: Allow arbitrary number free sba_request
Currently, we cannot have any arbitrary number of free sba_request
because sba_prealloc_channel_resources() allocates an array of
sba_request using devm_kcalloc() and kcalloc() cannot provide
memory beyond certain size.
This patch removes "reqs" (sba_request array) from sba_device
and makes "cmds" as variable array (instead of pointer) in
sba_request. This helps sba_prealloc_channel_resources() to
allocate sba_request and associated SBA command in one allocation
which in-turn allows arbitrary number of free sba_request.
Signed-off-by: Anup Patel <anup.patel@broadcom.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/bcm-sba-raid.c | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/drivers/dma/bcm-sba-raid.c b/drivers/dma/bcm-sba-raid.c index fdc9891f1e2f..9ab2d955ee14 100644 --- a/drivers/dma/bcm-sba-raid.c +++ b/drivers/dma/bcm-sba-raid.c @@ -113,9 +113,10 @@ struct sba_request { struct list_head next; atomic_t next_pending_count; /* BRCM message data */ - struct brcm_sba_command *cmds; struct brcm_message msg; struct dma_async_tx_descriptor tx; + /* SBA commands */ + struct brcm_sba_command cmds[0]; }; enum sba_version { @@ -153,7 +154,6 @@ struct sba_device { void *cmds_base; dma_addr_t cmds_dma_base; spinlock_t reqs_lock; - struct sba_request *reqs; bool reqs_fence; struct list_head reqs_alloc_list; struct list_head reqs_pending_list; @@ -1484,26 +1484,20 @@ static int sba_prealloc_channel_resources(struct sba_device *sba) INIT_LIST_HEAD(&sba->reqs_aborted_list); INIT_LIST_HEAD(&sba->reqs_free_list); - sba->reqs = devm_kcalloc(sba->dev, sba->max_req, - sizeof(*req), GFP_KERNEL); - if (!sba->reqs) { - ret = -ENOMEM; - goto fail_free_cmds_pool; - } - for (i = 0; i < sba->max_req; i++) { - req = &sba->reqs[i]; + req = devm_kzalloc(sba->dev, + sizeof(*req) + + sba->max_cmd_per_req * sizeof(req->cmds[0]), + GFP_KERNEL); + if (!req) { + ret = -ENOMEM; + goto fail_free_cmds_pool; + } INIT_LIST_HEAD(&req->node); req->sba = sba; req->flags = SBA_REQUEST_STATE_FREE; INIT_LIST_HEAD(&req->next); atomic_set(&req->next_pending_count, 0); - req->cmds = devm_kcalloc(sba->dev, sba->max_cmd_per_req, - sizeof(*req->cmds), GFP_KERNEL); - if (!req->cmds) { - ret = -ENOMEM; - goto fail_free_cmds_pool; - } for (j = 0; j < sba->max_cmd_per_req; j++) { req->cmds[j].cmd = 0; req->cmds[j].cmd_dma = sba->cmds_base + |