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

Commit 33811026 authored by Robert Elliott's avatar Robert Elliott Committed by James Bottomley
Browse files

hpsa: optimize cmd_alloc function by remembering last allocation



Empirically, this improves performance slightly (~2% max IOPS) by
allowing cmd_alloc to remember where it left off searching for
free commands between calls instead of always starting its search
at command 0.

Reviewed-by: default avatarScott Teel <scott.teel@pmcs.com>
Signed-off-by: default avatarRobert Elliott <elliott@hp.com>
Signed-off-by: default avatarDon Brace <don.brace@pmcs.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 281a7fd0
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -4649,9 +4649,10 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
	union u64bit temp64;
	union u64bit temp64;
	dma_addr_t cmd_dma_handle, err_dma_handle;
	dma_addr_t cmd_dma_handle, err_dma_handle;
	int refcount;
	int refcount;
	unsigned long offset = 0;
	unsigned long offset;


	/* There is some *extremely* small but non-zero chance that that
	/*
	 * There is some *extremely* small but non-zero chance that that
	 * multiple threads could get in here, and one thread could
	 * multiple threads could get in here, and one thread could
	 * be scanning through the list of bits looking for a free
	 * be scanning through the list of bits looking for a free
	 * one, but the free ones are always behind him, and other
	 * one, but the free ones are always behind him, and other
@@ -4662,6 +4663,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
	 * infrequently as to be indistinguishable from never.
	 * infrequently as to be indistinguishable from never.
	 */
	 */


	offset = h->last_allocation; /* benignly racy */
	for (;;) {
	for (;;) {
		i = find_next_zero_bit(h->cmd_pool_bits, h->nr_cmds, offset);
		i = find_next_zero_bit(h->cmd_pool_bits, h->nr_cmds, offset);
		if (unlikely(i == h->nr_cmds)) {
		if (unlikely(i == h->nr_cmds)) {
@@ -4679,6 +4681,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
			h->cmd_pool_bits + (i / BITS_PER_LONG));
			h->cmd_pool_bits + (i / BITS_PER_LONG));
		break; /* it's ours now. */
		break; /* it's ours now. */
	}
	}
	h->last_allocation = i; /* benignly racy */


	/* Zero out all of commandlist except the last field, refcount */
	/* Zero out all of commandlist except the last field, refcount */
	memset(c, 0, offsetof(struct CommandList, refcount));
	memset(c, 0, offsetof(struct CommandList, refcount));
+1 −0
Original line number Original line Diff line number Diff line
@@ -133,6 +133,7 @@ struct ctlr_info {
	struct CfgTable __iomem *cfgtable;
	struct CfgTable __iomem *cfgtable;
	int	interrupts_enabled;
	int	interrupts_enabled;
	int 	max_commands;
	int 	max_commands;
	int last_allocation;
	atomic_t commands_outstanding;
	atomic_t commands_outstanding;
#	define PERF_MODE_INT	0
#	define PERF_MODE_INT	0
#	define DOORBELL_INT	1
#	define DOORBELL_INT	1