Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 072b0518 authored by Stephen M. Cameron's avatar Stephen M. Cameron Committed by Christoph Hellwig
Browse files

hpsa: allocate reply queues individually



Now that we can allocate more than 4 reply queues (up to 64)
we shouldn't try to make them share the same allocation but
should allocate them separately.

Signed-off-by: default avatarStephen M. Cameron <scameron@beardog.cce.hp.com>
Reviewed-by: default avatarMike Miller <michael.miller@canonical.com>
Reviewed-by: default avatarScott Teel <scott.teel@hp.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent f89439bc
Loading
Loading
Loading
Loading
+32 −21
Original line number Diff line number Diff line
@@ -695,7 +695,7 @@ static inline void addQ(struct list_head *list, struct CommandList *c)
static inline u32 next_command(struct ctlr_info *h, u8 q)
{
	u32 a;
	struct reply_pool *rq = &h->reply_queue[q];
	struct reply_queue_buffer *rq = &h->reply_queue[q];
	unsigned long flags;

	if (h->transMethod & CFGTBL_Trans_io_accel1)
@@ -6707,6 +6707,20 @@ static void hpsa_free_irqs_and_disable_msix(struct ctlr_info *h)
#endif /* CONFIG_PCI_MSI */
}

static void hpsa_free_reply_queues(struct ctlr_info *h)
{
	int i;

	for (i = 0; i < h->nreply_queues; i++) {
		if (!h->reply_queue[i].head)
			continue;
		pci_free_consistent(h->pdev, h->reply_queue_size,
			h->reply_queue[i].head, h->reply_queue[i].busaddr);
		h->reply_queue[i].head = NULL;
		h->reply_queue[i].busaddr = 0;
	}
}

static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
{
	hpsa_free_irqs_and_disable_msix(h);
@@ -6714,8 +6728,7 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
	hpsa_free_cmd_pool(h);
	kfree(h->ioaccel1_blockFetchTable);
	kfree(h->blockFetchTable);
	pci_free_consistent(h->pdev, h->reply_pool_size,
		h->reply_pool, h->reply_pool_dhandle);
	hpsa_free_reply_queues(h);
	if (h->vaddr)
		iounmap(h->vaddr);
	if (h->transtable)
@@ -7164,8 +7177,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
	pci_free_consistent(h->pdev,
		h->nr_cmds * sizeof(struct ErrorInfo),
		h->errinfo_pool, h->errinfo_pool_dhandle);
	pci_free_consistent(h->pdev, h->reply_pool_size,
		h->reply_pool, h->reply_pool_dhandle);
	hpsa_free_reply_queues(h);
	kfree(h->cmd_pool_bits);
	kfree(h->blockFetchTable);
	kfree(h->ioaccel1_blockFetchTable);
@@ -7278,7 +7290,8 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
	 */

	/* Controller spec: zero out this buffer. */
	memset(h->reply_pool, 0, h->reply_pool_size);
	for (i = 0; i < h->nreply_queues; i++)
		memset(h->reply_queue[i].head, 0, h->reply_queue_size);

	bft[7] = SG_ENTRIES_IN_CMD + 4;
	calc_bucket_map(bft, ARRAY_SIZE(bft),
@@ -7294,8 +7307,7 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)

	for (i = 0; i < h->nreply_queues; i++) {
		writel(0, &h->transtable->RepQAddr[i].upper);
		writel(h->reply_pool_dhandle +
			(h->max_commands * sizeof(u64) * i),
		writel(h->reply_queue[i].busaddr,
			&h->transtable->RepQAddr[i].lower);
	}

@@ -7343,8 +7355,10 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support)
				h->ioaccel1_blockFetchTable);

		/* initialize all reply queue entries to unused */
		memset(h->reply_pool, (u8) IOACCEL_MODE1_REPLY_UNUSED,
				h->reply_pool_size);
		for (i = 0; i < h->nreply_queues; i++)
			memset(h->reply_queue[i].head,
				(u8) IOACCEL_MODE1_REPLY_UNUSED,
				h->reply_queue_size);

		/* set all the constant fields in the accelerator command
		 * frames once at init time to save CPU cycles later.
@@ -7500,16 +7514,17 @@ static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
		}
	}

	/* TODO, check that this next line h->nreply_queues is correct */
	h->nreply_queues = h->msix_vector > 0 ? h->msix_vector : 1;
	hpsa_get_max_perf_mode_cmds(h);
	/* Performant mode ring buffer and supporting data structures */
	h->reply_pool_size = h->max_commands * sizeof(u64) * h->nreply_queues;
	h->reply_pool = pci_alloc_consistent(h->pdev, h->reply_pool_size,
				&(h->reply_pool_dhandle));
	h->reply_queue_size = h->max_commands * sizeof(u64);

	for (i = 0; i < h->nreply_queues; i++) {
		h->reply_queue[i].head = &h->reply_pool[h->max_commands * i];
		h->reply_queue[i].head = pci_alloc_consistent(h->pdev,
						h->reply_queue_size,
						&(h->reply_queue[i].busaddr));
		if (!h->reply_queue[i].head)
			goto clean_up;
		h->reply_queue[i].size = h->max_commands;
		h->reply_queue[i].wraparound = 1;  /* spec: init to 1 */
		h->reply_queue[i].current_entry = 0;
@@ -7518,18 +7533,14 @@ static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
	/* Need a block fetch table for performant mode */
	h->blockFetchTable = kmalloc(((SG_ENTRIES_IN_CMD + 1) *
				sizeof(u32)), GFP_KERNEL);

	if ((h->reply_pool == NULL)
		|| (h->blockFetchTable == NULL))
	if (!h->blockFetchTable)
		goto clean_up;

	hpsa_enter_performant_mode(h, trans_support);
	return;

clean_up:
	if (h->reply_pool)
		pci_free_consistent(h->pdev, h->reply_pool_size,
			h->reply_pool, h->reply_pool_dhandle);
	hpsa_free_reply_queues(h);
	kfree(h->blockFetchTable);
}

+6 −7
Original line number Diff line number Diff line
@@ -57,11 +57,12 @@ struct hpsa_scsi_dev_t {

};

struct reply_pool {
struct reply_queue_buffer {
	u64 *head;
	size_t size;
	u8 wraparound;
	u32 current_entry;
	dma_addr_t busaddr;
};

#pragma pack(1)
@@ -174,11 +175,9 @@ struct ctlr_info {
	/*
	 * Performant mode completion buffers
	 */
	u64 *reply_pool;
	size_t reply_pool_size;
	struct reply_pool reply_queue[MAX_REPLY_QUEUES];
	size_t reply_queue_size;
	struct reply_queue_buffer reply_queue[MAX_REPLY_QUEUES];
	u8 nreply_queues;
	dma_addr_t reply_pool_dhandle;
	u32 *blockFetchTable;
	u32 *ioaccel1_blockFetchTable;
	u32 *ioaccel2_blockFetchTable;
@@ -392,7 +391,7 @@ static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)

static unsigned long SA5_performant_completed(struct ctlr_info *h, u8 q)
{
	struct reply_pool *rq = &h->reply_queue[q];
	struct reply_queue_buffer *rq = &h->reply_queue[q];
	unsigned long flags, register_value = FIFO_EMPTY;

	/* msi auto clears the interrupt pending bit. */
@@ -507,7 +506,7 @@ static bool SA5_ioaccel_mode1_intr_pending(struct ctlr_info *h)
static unsigned long SA5_ioaccel_mode1_completed(struct ctlr_info *h, u8 q)
{
	u64 register_value;
	struct reply_pool *rq = &h->reply_queue[q];
	struct reply_queue_buffer *rq = &h->reply_queue[q];
	unsigned long flags;

	BUG_ON(q >= h->nreply_queues);