From: Don Brace <don.brace@pmcs.com>
To: scott.teel@pmcs.com, Kevin.Barnett@pmcs.com,
james.bottomley@parallels.com, hch@infradead.org,
Justin.Lindley@pmcs.com, brace@pmcs.com
Cc: linux-scsi@vger.kernel.org
Subject: [PATCH 19/43] hpsa: add ioaccel sg chaining for the ioaccel2 path
Date: Sat, 21 Feb 2015 16:19:13 -0600 [thread overview]
Message-ID: <20150221221913.21954.2947.stgit@brunhilda> (raw)
In-Reply-To: <20150221221553.21954.32599.stgit@brunhilda>
From: Webb Scales <webbnh@hp.com>
Increase the request size for ioaccel2 path.
The error, if any, returned by hpsa_allocate_ioaccel2_sg_chain_blocks
to hpsa_alloc_ioaccel2_cmd_and_bft should be returned upstream rather
than assumed to be -ENOMEM.
This differs slightly from hpsa_alloc_ioaccel1_cmd_and_bft,
which does not call another hpsa_allocate function and only
has -ENOMEM to return from some kmalloc calls.
Reviewed-by: Scott Teel <scott.teel@pmcs.com>
Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
Signed-off-by: Robert Elliott <elliott@hp.com>
Signed-off-by: Don Brace <don.brace@pmcs.com>
---
drivers/scsi/hpsa.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++----
drivers/scsi/hpsa.h | 1
2 files changed, 116 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index e61e4eb..9cf7ed7 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1750,6 +1750,46 @@ static void hpsa_slave_destroy(struct scsi_device *sdev)
/* nothing to do. */
}
+static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h)
+{
+ int i;
+
+ if (!h->ioaccel2_cmd_sg_list)
+ return;
+ for (i = 0; i < h->nr_cmds; i++) {
+ kfree(h->ioaccel2_cmd_sg_list[i]);
+ h->ioaccel2_cmd_sg_list[i] = NULL;
+ }
+ kfree(h->ioaccel2_cmd_sg_list);
+ h->ioaccel2_cmd_sg_list = NULL;
+}
+
+static int hpsa_allocate_ioaccel2_sg_chain_blocks(struct ctlr_info *h)
+{
+ int i;
+
+ if (h->chainsize <= 0)
+ return 0;
+
+ h->ioaccel2_cmd_sg_list =
+ kzalloc(sizeof(*h->ioaccel2_cmd_sg_list) * h->nr_cmds,
+ GFP_KERNEL);
+ if (!h->ioaccel2_cmd_sg_list)
+ return -ENOMEM;
+ for (i = 0; i < h->nr_cmds; i++) {
+ h->ioaccel2_cmd_sg_list[i] =
+ kmalloc(sizeof(*h->ioaccel2_cmd_sg_list[i]) *
+ h->maxsgentries, GFP_KERNEL);
+ if (!h->ioaccel2_cmd_sg_list[i])
+ goto clean;
+ }
+ return 0;
+
+clean:
+ hpsa_free_ioaccel2_sg_chain_blocks(h);
+ return -ENOMEM;
+}
+
static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
{
int i;
@@ -1792,6 +1832,39 @@ clean:
return -ENOMEM;
}
+static int hpsa_map_ioaccel2_sg_chain_block(struct ctlr_info *h,
+ struct io_accel2_cmd *cp, struct CommandList *c)
+{
+ struct ioaccel2_sg_element *chain_block;
+ u64 temp64;
+ u32 chain_size;
+
+ chain_block = h->ioaccel2_cmd_sg_list[c->cmdindex];
+ chain_size = le32_to_cpu(cp->data_len);
+ temp64 = pci_map_single(h->pdev, chain_block, chain_size,
+ PCI_DMA_TODEVICE);
+ if (dma_mapping_error(&h->pdev->dev, temp64)) {
+ /* prevent subsequent unmapping */
+ cp->sg->address = 0;
+ return -1;
+ }
+ cp->sg->address = cpu_to_le64(temp64);
+ return 0;
+}
+
+static void hpsa_unmap_ioaccel2_sg_chain_block(struct ctlr_info *h,
+ struct io_accel2_cmd *cp)
+{
+ struct ioaccel2_sg_element *chain_sg;
+ u64 temp64;
+ u32 chain_size;
+
+ chain_sg = cp->sg;
+ temp64 = le64_to_cpu(chain_sg->address);
+ chain_size = le32_to_cpu(cp->data_len);
+ pci_unmap_single(h->pdev, temp64, chain_size, PCI_DMA_TODEVICE);
+}
+
static int hpsa_map_sg_chain_block(struct ctlr_info *h,
struct CommandList *c)
{
@@ -2001,6 +2074,7 @@ static void complete_scsi_command(struct CommandList *cp)
struct ctlr_info *h;
struct ErrorInfo *ei;
struct hpsa_scsi_dev_t *dev;
+ struct io_accel2_cmd *c2;
int sense_key;
int asc; /* additional sense code */
@@ -2011,12 +2085,17 @@ static void complete_scsi_command(struct CommandList *cp)
cmd = cp->scsi_cmd;
h = cp->h;
dev = cmd->device->hostdata;
+ c2 = &h->ioaccel2_cmd_pool[cp->cmdindex];
scsi_dma_unmap(cmd); /* undo the DMA mappings */
if ((cp->cmd_type == CMD_SCSI) &&
(le16_to_cpu(cp->Header.SGTotal) > h->max_cmd_sg_entries))
hpsa_unmap_sg_chain_block(h, cp);
+ if ((cp->cmd_type == CMD_IOACCEL2) &&
+ (c2->sg[0].chain_indicator == IOACCEL2_CHAIN))
+ hpsa_unmap_ioaccel2_sg_chain_block(h, c2);
+
cmd->result = (DID_OK << 16); /* host byte */
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
@@ -3858,10 +3937,7 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
u32 len;
u32 total_len = 0;
- if (scsi_sg_count(cmd) > h->ioaccel_maxsg) {
- atomic_dec(&phys_disk->ioaccel_cmds_out);
- return IO_ACCEL_INELIGIBLE;
- }
+ BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
if (fixup_ioaccel_cdb(cdb, &cdb_len)) {
atomic_dec(&phys_disk->ioaccel_cmds_out);
@@ -3884,8 +3960,19 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
}
if (use_sg) {
- BUG_ON(use_sg > IOACCEL2_MAXSGENTRIES);
curr_sg = cp->sg;
+ if (use_sg > h->ioaccel_maxsg) {
+ addr64 = le64_to_cpu(
+ h->ioaccel2_cmd_sg_list[c->cmdindex]->address);
+ curr_sg->address = cpu_to_le64(addr64);
+ curr_sg->length = 0;
+ curr_sg->reserved[0] = 0;
+ curr_sg->reserved[1] = 0;
+ curr_sg->reserved[2] = 0;
+ curr_sg->chain_indicator = 0x80;
+
+ curr_sg = h->ioaccel2_cmd_sg_list[c->cmdindex];
+ }
scsi_for_each_sg(cmd, sg, use_sg, i) {
addr64 = (u64) sg_dma_address(sg);
len = sg_dma_len(sg);
@@ -3930,14 +4017,22 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
cp->Tag = cpu_to_le32(c->cmdindex << DIRECT_LOOKUP_SHIFT);
memcpy(cp->cdb, cdb, sizeof(cp->cdb));
- /* fill in sg elements */
- cp->sg_count = (u8) use_sg;
-
cp->data_len = cpu_to_le32(total_len);
cp->err_ptr = cpu_to_le64(c->busaddr +
offsetof(struct io_accel2_cmd, error_data));
cp->err_len = cpu_to_le32(sizeof(cp->error_data));
+ /* fill in sg elements */
+ if (use_sg > h->ioaccel_maxsg) {
+ cp->sg_count = 1;
+ if (hpsa_map_ioaccel2_sg_chain_block(h, cp, c)) {
+ atomic_dec(&phys_disk->ioaccel_cmds_out);
+ scsi_dma_unmap(cmd);
+ return -1;
+ }
+ } else
+ cp->sg_count = (u8) use_sg;
+
enqueue_cmd_and_start_io(h, c);
return 0;
}
@@ -7950,6 +8045,8 @@ clean_up:
/* Free ioaccel2 mode command blocks and block fetch table */
static void hpsa_free_ioaccel2_cmd_and_bft(struct ctlr_info *h)
{
+ hpsa_free_ioaccel2_sg_chain_blocks(h);
+
if (h->ioaccel2_cmd_pool)
pci_free_consistent(h->pdev,
h->nr_cmds * sizeof(*h->ioaccel2_cmd_pool),
@@ -7961,6 +8058,8 @@ static void hpsa_free_ioaccel2_cmd_and_bft(struct ctlr_info *h)
/* Allocate ioaccel2 mode command blocks and block fetch table */
static int hpsa_alloc_ioaccel2_cmd_and_bft(struct ctlr_info *h)
{
+ int rc;
+
/* Allocate ioaccel2 mode command blocks and block fetch table */
h->ioaccel_maxsg =
@@ -7980,7 +8079,13 @@ static int hpsa_alloc_ioaccel2_cmd_and_bft(struct ctlr_info *h)
sizeof(u32)), GFP_KERNEL);
if ((h->ioaccel2_cmd_pool == NULL) ||
- (h->ioaccel2_blockFetchTable == NULL))
+ (h->ioaccel2_blockFetchTable == NULL)) {
+ rc = -ENOMEM;
+ goto clean_up;
+ }
+
+ rc = hpsa_allocate_ioaccel2_sg_chain_blocks(h);
+ if (rc)
goto clean_up;
memset(h->ioaccel2_cmd_pool, 0,
@@ -7989,7 +8094,7 @@ static int hpsa_alloc_ioaccel2_cmd_and_bft(struct ctlr_info *h)
clean_up:
hpsa_free_ioaccel2_cmd_and_bft(h);
- return 1;
+ return rc;
}
static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 87a70b5..3acacf6 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -162,6 +162,7 @@ struct ctlr_info {
u8 max_cmd_sg_entries;
int chainsize;
struct SGDescriptor **cmd_sg_list;
+ struct ioaccel2_sg_element **ioaccel2_cmd_sg_list;
/* pointers to command and error info pool */
struct CommandList *cmd_pool;
next prev parent reply other threads:[~2015-02-21 22:20 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-21 22:17 [PATCH 00/43] hpsa updates Don Brace
2015-02-21 22:17 ` [PATCH 01/43] hpsa: add masked physical devices into h->dev[] array Don Brace
2015-02-23 20:14 ` Christoph Hellwig
2015-02-26 15:17 ` brace
2015-03-05 13:34 ` Christoph Hellwig
2015-02-21 22:17 ` [PATCH 02/43] hpsa: clean up host, channel, target, lun prints Don Brace
2015-02-23 20:16 ` Christoph Hellwig
2015-02-26 14:50 ` brace
2015-02-21 22:17 ` [PATCH 03/43] hpsa: rework controller command submission Don Brace
2015-02-21 22:17 ` [PATCH 04/43] hpsa: clean up aborts Don Brace
2015-02-21 22:17 ` [PATCH 05/43] hpsa: decrement h->commands_outstanding in fail_all_outstanding_cmds Don Brace
2015-02-21 22:18 ` [PATCH 06/43] hpsa: hpsa decode sense data for io and tmf Don Brace
2015-02-23 20:18 ` Christoph Hellwig
2015-02-25 18:06 ` brace
2015-02-21 22:18 ` [PATCH 07/43] hpsa: allow lockup detected to be viewed via sysfs Don Brace
2015-02-21 22:18 ` [PATCH 08/43] hpsa: make function names consistent Don Brace
2015-02-21 22:18 ` [PATCH 09/43] hpsa: factor out hpsa_init_cmd function Don Brace
2015-02-21 22:18 ` [PATCH 10/43] hpsa: do not ignore return value of hpsa_register_scsi Don Brace
2015-02-23 20:18 ` Christoph Hellwig
2015-02-21 22:18 ` [PATCH 11/43] hpsa: try resubmitting down raid path on task set full Don Brace
2015-02-21 22:18 ` [PATCH 12/43] hpsa: factor out hpsa_ioaccel_submit function Don Brace
2015-02-21 22:18 ` [PATCH 13/43] hpsa: print accurate SSD Smart Path Enabled status Don Brace
2015-02-21 22:18 ` [PATCH 14/43] hpsa: use ioaccel2 path to submit IOs to physical drives in HBA mode Don Brace
2015-02-21 22:18 ` [PATCH 15/43] hpsa: Get queue depth from identify physical bmic for physical disks Don Brace
2015-02-21 22:18 ` [PATCH 16/43] hpsa: break hpsa_free_irqs_and_disable_msix into two functions Don Brace
2015-02-21 22:19 ` [PATCH 17/43] hpsa: clean up error handling Don Brace
2015-02-21 22:19 ` [PATCH 18/43] hpsa: refactor freeing of resources into more logical functions Don Brace
2015-02-21 22:19 ` Don Brace [this message]
2015-02-21 22:19 ` [PATCH 20/43] hpsa: add more ioaccel2 error handling, including underrun statuses Don Brace
2015-02-21 22:19 ` [PATCH 21/43] hpsa: do not check cmd_alloc return value - it cannnot return NULL Don Brace
2015-02-21 22:19 ` [PATCH 22/43] hpsa: correct return values from driver functions Don Brace
2015-02-21 22:19 ` [PATCH 23/43] hpsa: clean up driver init Don Brace
2015-02-21 22:19 ` [PATCH 24/43] hpsa: clean up some error reporting output in abort handler Don Brace
2015-02-21 22:19 ` [PATCH 25/43] hpsa: do not print ioaccel2 warning messages about unusual completions Don Brace
2015-02-21 22:19 ` [PATCH 26/43] hpsa: add support sending aborts to physical devices via the ioaccel2 path Don Brace
2015-02-21 22:19 ` [PATCH 27/43] hpsa: use helper routines for finishing commands Don Brace
2015-02-21 22:20 ` [PATCH 28/43] hpsa: don't return abort request until target is complete Don Brace
2015-02-21 22:20 ` [PATCH 29/43] hpsa: refactor and rework support for sending TEST_UNIT_READY Don Brace
2015-02-21 22:20 ` [PATCH 30/43] hpsa: performance tweak for hpsa_scatter_gather() Don Brace
2015-02-21 22:20 ` [PATCH 31/43] hpsa: call pci_release_regions after pci_disable_device Don Brace
2015-02-21 22:20 ` [PATCH 32/43] hpsa: skip free_irq calls if irqs are not allocated Don Brace
2015-02-21 22:20 ` [PATCH 33/43] hpsa: cleanup for init_one step 2 in kdump Don Brace
2015-02-21 22:20 ` [PATCH 34/43] hpsa: fix try_soft_reset error handling Don Brace
2015-02-21 22:20 ` [PATCH 35/43] hpsa: create workqueue after the driver is ready for use Don Brace
2015-02-21 22:20 ` [PATCH 36/43] hpsa: add interrupt number to /proc/interrupts interrupt name Don Brace
2015-02-21 22:20 ` [PATCH 37/43] hpsa: use block layer tag for command allocation Don Brace
2015-02-23 20:25 ` Christoph Hellwig
2015-02-24 20:51 ` brace
2015-02-21 22:20 ` [PATCH 38/43] hpsa: clean up new block layer tag error handling Don Brace
2015-02-23 20:25 ` Christoph Hellwig
2015-02-24 17:39 ` brace
2015-02-21 22:21 ` [PATCH 39/43] hpsa: use scsi host_no as hpsa controller number Don Brace
2015-02-21 22:21 ` [PATCH 40/43] hpsa: cleanup initialization code Don Brace
2015-02-23 20:26 ` Christoph Hellwig
2015-02-24 21:29 ` brace
2015-02-21 22:21 ` [PATCH 41/43] hpsa: propagate the error code in hpsa_kdump_soft_reset Don Brace
2015-02-21 22:21 ` [PATCH 42/43] hpsa: cleanup reset Don Brace
2015-02-21 22:21 ` [PATCH 43/43] hpsa: change driver version Don Brace
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150221221913.21954.2947.stgit@brunhilda \
--to=don.brace@pmcs.com \
--cc=Justin.Lindley@pmcs.com \
--cc=Kevin.Barnett@pmcs.com \
--cc=brace@pmcs.com \
--cc=hch@infradead.org \
--cc=james.bottomley@parallels.com \
--cc=linux-scsi@vger.kernel.org \
--cc=scott.teel@pmcs.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox