2006-11-01 21:56:45

by Mike Miller (OS Dev)

[permalink] [raw]
Subject: [PATCH 3/8] cciss: change number of commands per controller


PATCH 3/11

This patch removes #define NR_CMDS and replaces it w/hba[i]->nr_cmds. Most
Smart Array controllers can support up to 1024 commands but the E200 family
can only support 128. To prevent annoying "fifo full" messages we define
nr_cmds on a per controller basis by adding it the product table.
Please consider this for inclusion.

Thanks,
mikem

Signed-off-by: Mike Miller <[email protected]>

cciss.c | 74 ++++++++++++++++++++++++++++++++--------------------------------
cciss.h | 2 +
2 files changed, 40 insertions(+), 36 deletions(-)
--------------------------------------------------------------------------------
diff -urNp linux-2.6-p00002/drivers/block/cciss.c linux-2.6/drivers/block/cciss.c
--- linux-2.6-p00002/drivers/block/cciss.c 2006-10-31 14:52:09.000000000 -0600
+++ linux-2.6/drivers/block/cciss.c 2006-10-31 15:05:49.000000000 -0600
@@ -93,28 +93,29 @@ MODULE_DEVICE_TABLE(pci, cciss_pci_devic
/* board_id = Subsystem Device ID & Vendor ID
* product = Marketing Name for the board
* access = Address of the struct of function pointers
+ * nr_cmds = Number of commands supported by controller
*/
static struct board_type products[] = {
- {0x40700E11, "Smart Array 5300", &SA5_access},
- {0x40800E11, "Smart Array 5i", &SA5B_access},
- {0x40820E11, "Smart Array 532", &SA5B_access},
- {0x40830E11, "Smart Array 5312", &SA5B_access},
- {0x409A0E11, "Smart Array 641", &SA5_access},
- {0x409B0E11, "Smart Array 642", &SA5_access},
- {0x409C0E11, "Smart Array 6400", &SA5_access},
- {0x409D0E11, "Smart Array 6400 EM", &SA5_access},
- {0x40910E11, "Smart Array 6i", &SA5_access},
- {0x3225103C, "Smart Array P600", &SA5_access},
- {0x3223103C, "Smart Array P800", &SA5_access},
- {0x3234103C, "Smart Array P400", &SA5_access},
- {0x3235103C, "Smart Array P400i", &SA5_access},
- {0x3211103C, "Smart Array E200i", &SA5_access},
- {0x3212103C, "Smart Array E200", &SA5_access},
- {0x3213103C, "Smart Array E200i", &SA5_access},
- {0x3214103C, "Smart Array E200i", &SA5_access},
- {0x3215103C, "Smart Array E200i", &SA5_access},
- {0x3233103C, "Smart Array E500", &SA5_access},
- {0xFFFF103C, "Unknown Smart Array", &SA5_access},
+ {0x40700E11, "Smart Array 5300", &SA5_access, 512},
+ {0x40800E11, "Smart Array 5i", &SA5B_access, 512},
+ {0x40820E11, "Smart Array 532", &SA5B_access, 512},
+ {0x40830E11, "Smart Array 5312", &SA5B_access, 512},
+ {0x409A0E11, "Smart Array 641", &SA5_access, 512},
+ {0x409B0E11, "Smart Array 642", &SA5_access, 512},
+ {0x409C0E11, "Smart Array 6400", &SA5_access, 512},
+ {0x409D0E11, "Smart Array 6400 EM", &SA5_access, 512},
+ {0x40910E11, "Smart Array 6i", &SA5_access, 512},
+ {0x3225103C, "Smart Array P600", &SA5_access, 512},
+ {0x3223103C, "Smart Array P800", &SA5_access, 512},
+ {0x3234103C, "Smart Array P400", &SA5_access, 512},
+ {0x3235103C, "Smart Array P400i", &SA5_access, 512},
+ {0x3211103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3212103C, "Smart Array E200", &SA5_access, 120},
+ {0x3213103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3214103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3215103C, "Smart Array E200i", &SA5_access, 120},
+ {0x3233103C, "Smart Array E500", &SA5_access, 512},
+ {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120},
};

/* How long to wait (in milliseconds) for board to go into simple mode */
@@ -125,7 +126,6 @@ static struct board_type products[] = {
#define MAX_CMD_RETRIES 3

#define READ_AHEAD 1024
-#define NR_CMDS 384 /* #commands that can be outstanding */
#define MAX_CTLR 32

/* Originally cciss driver only supports 8 major numbers */
@@ -404,8 +404,8 @@ static CommandList_struct *cmd_alloc(ctl
} else { /* get it out of the controllers pool */

do {
- i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS);
- if (i == NR_CMDS)
+ i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds);
+ if (i == h->nr_cmds)
return NULL;
} while (test_and_set_bit
(i & (BITS_PER_LONG - 1),
@@ -1247,7 +1247,7 @@ static void cciss_check_queues(ctlr_info
* in case the interrupt we serviced was from an ioctl and did not
* free any new commands.
*/
- if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
+ if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds)
return;

/* We have room on the queue for more commands. Now we need to queue
@@ -1266,7 +1266,7 @@ static void cciss_check_queues(ctlr_info
/* check to see if we have maxed out the number of commands
* that can be placed on the queue.
*/
- if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
+ if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds) {
if (curr_queue == start_queue) {
h->next_to_run =
(start_queue + 1) % (h->highest_lun + 1);
@@ -2134,7 +2134,7 @@ static int add_sendcmd_reject(__u8 cmd,

/* We've sent down an abort or reset, but something else
has completed */
- if (srl->ncompletions >= (NR_CMDS + 2)) {
+ if (srl->ncompletions >= (hba[ctlr]->nr_cmds + 2)) {
/* Uh oh. No room to save it for later... */
printk(KERN_WARNING "cciss%d: Sendcmd: Invalid command addr, "
"reject list overflow, command lost!\n", ctlr);
@@ -2671,7 +2671,7 @@ static irqreturn_t do_cciss_intr(int irq
a1 = a;
if ((a & 0x04)) {
a2 = (a >> 3);
- if (a2 >= NR_CMDS) {
+ if (a2 >= h->nr_cmds) {
printk(KERN_WARNING
"cciss: controller cciss%d failed, stopping.\n",
h->ctlr);
@@ -2954,6 +2954,7 @@ static int cciss_pci_init(ctlr_info_t *c
if (board_id == products[i].board_id) {
c->product_name = products[i].product_name;
c->access = *(products[i].access);
+ c->nr_cmds = products[i].nr_cmds;
break;
}
}
@@ -2973,6 +2974,7 @@ static int cciss_pci_init(ctlr_info_t *c
if (subsystem_vendor_id == PCI_VENDOR_ID_HP) {
c->product_name = products[i-1].product_name;
c->access = *(products[i-1].access);
+ c->nr_cmds = products[i-1].nr_cmds;
printk(KERN_WARNING "cciss: This is an unknown "
"Smart Array controller.\n"
"cciss: Please update to the latest driver "
@@ -3280,15 +3282,15 @@ static int __devinit cciss_init_one(stru
hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not");

hba[i]->cmd_pool_bits =
- kmalloc(((NR_CMDS + BITS_PER_LONG -
+ kmalloc(((hba[i]->nr_cmds + BITS_PER_LONG -
1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
hba[i]->cmd_pool = (CommandList_struct *)
pci_alloc_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(CommandList_struct),
+ hba[i]->nr_cmds * sizeof(CommandList_struct),
&(hba[i]->cmd_pool_dhandle));
hba[i]->errinfo_pool = (ErrorInfo_struct *)
pci_alloc_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(ErrorInfo_struct),
+ hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
&(hba[i]->errinfo_pool_dhandle));
if ((hba[i]->cmd_pool_bits == NULL)
|| (hba[i]->cmd_pool == NULL)
@@ -3299,7 +3301,7 @@ static int __devinit cciss_init_one(stru
#ifdef CONFIG_CISS_SCSI_TAPE
hba[i]->scsi_rejects.complete =
kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) *
- (NR_CMDS + 5), GFP_KERNEL);
+ (hba[i]->nr_cmds + 5), GFP_KERNEL);
if (hba[i]->scsi_rejects.complete == NULL) {
printk(KERN_ERR "cciss: out of memory");
goto clean4;
@@ -3313,7 +3315,7 @@ static int __devinit cciss_init_one(stru
/* command and error info recs zeroed out before
they are used */
memset(hba[i]->cmd_pool_bits, 0,
- ((NR_CMDS + BITS_PER_LONG -
+ ((hba[i]->nr_cmds + BITS_PER_LONG -
1) / BITS_PER_LONG) * sizeof(unsigned long));

#ifdef CCISS_DEBUG
@@ -3382,11 +3384,11 @@ static int __devinit cciss_init_one(stru
kfree(hba[i]->cmd_pool_bits);
if (hba[i]->cmd_pool)
pci_free_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(CommandList_struct),
+ hba[i]->nr_cmds * sizeof(CommandList_struct),
hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
if (hba[i]->errinfo_pool)
pci_free_consistent(hba[i]->pdev,
- NR_CMDS * sizeof(ErrorInfo_struct),
+ hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
hba[i]->errinfo_pool,
hba[i]->errinfo_pool_dhandle);
free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]);
@@ -3453,9 +3455,9 @@ static void __devexit cciss_remove_one(s
}
}

- pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
+ pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct),
hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
- pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(ErrorInfo_struct),
+ pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
kfree(hba[i]->cmd_pool_bits);
#ifdef CONFIG_CISS_SCSI_TAPE
diff -urNp linux-2.6-p00002/drivers/block/cciss.h linux-2.6/drivers/block/cciss.h
--- linux-2.6-p00002/drivers/block/cciss.h 2006-10-31 14:31:05.000000000 -0600
+++ linux-2.6/drivers/block/cciss.h 2006-10-31 14:57:27.000000000 -0600
@@ -60,6 +60,7 @@ struct ctlr_info
__u32 board_id;
void __iomem *vaddr;
unsigned long paddr;
+ int nr_cmds; /* Number of commands allowed on this controller */
CfgTable_struct __iomem *cfgtable;
int interrupts_enabled;
int major;
@@ -282,6 +283,7 @@ struct board_type {
__u32 board_id;
char *product_name;
struct access_method *access;
+ int nr_cmds; /* Max cmds this kind of ctlr can handle. */
};

#define CCISS_LOCK(i) (&hba[i]->lock)


2006-11-02 14:10:00

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH 3/8] cciss: change number of commands per controller

On Wed, Nov 01 2006, Mike Miller (OS Dev) wrote:
> + {0x3211103C, "Smart Array E200i", &SA5_access, 120},

Is it 120, or 128? And how big is the allocated command array now, with
512 commands?

--
Jens Axboe

2006-11-02 14:33:22

by Mike Miller (OS Dev)

[permalink] [raw]
Subject: Re: [PATCH 3/8] cciss: change number of commands per controller

On Thu, Nov 02, 2006 at 03:11:50PM +0100, Jens Axboe wrote:
> On Wed, Nov 01 2006, Mike Miller (OS Dev) wrote:
> > + {0x3211103C, "Smart Array E200i", &SA5_access, 120},
>
> Is it 120, or 128? And how big is the allocated command array now, with
> 512 commands?

The controller can handle up to 128, but I artificially limited it to 120
for reasons I shouldn't discuss in public. :)

Each command is 548 bytes w/o scatter gather chaining. So 548 * 512 = 280576
bytes for the command list. We've tested using 1024 commands with several
Smart Array controllers and have not encountered issues. The reason for the
increase is performance. The busier you can keep the controller the better
it works.

mikem

2006-11-02 14:37:56

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH 3/8] cciss: change number of commands per controller

On Thu, Nov 02 2006, Mike Miller (OS Dev) wrote:
> On Thu, Nov 02, 2006 at 03:11:50PM +0100, Jens Axboe wrote:
> > On Wed, Nov 01 2006, Mike Miller (OS Dev) wrote:
> > > + {0x3211103C, "Smart Array E200i", &SA5_access, 120},
> >
> > Is it 120, or 128? And how big is the allocated command array now, with
> > 512 commands?
>
> The controller can handle up to 128, but I artificially limited it to 120
> for reasons I shouldn't discuss in public. :)

:-)

> Each command is 548 bytes w/o scatter gather chaining. So 548 * 512 = 280576
> bytes for the command list. We've tested using 1024 commands with several
> Smart Array controllers and have not encountered issues. The reason for the
> increase is performance. The busier you can keep the controller the better
> it works.

So this:

hba[i]->cmd_pool = (CommandList_struct *)
pci_alloc_consistent(hba[i]->pdev,
NR_CMDS * sizeof(CommandList_struct),
&(hba[i]->cmd_pool_dhandle));

is getting pretty huge then (it was already, actually).

--
Jens Axboe