Re: [PATCH 14/31] hpsa: use reserved commands

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 3/11/21 11:03 PM, michael.christie@xxxxxxxxxx wrote:
> On 2/22/21 7:23 AM, Hannes Reinecke wrote:
>> -
>> -static struct CommandList *cmd_alloc(struct ctlr_info *h)
>> +static struct CommandList *cmd_alloc(struct ctlr_info *h, u8 direction)
>>  {
>> +	struct scsi_cmnd *scmd;
>>  	struct CommandList *c;
>> -	int refcount, i;
>> -	int offset = 0;
>> -
>> -	/*
>> -	 * There is some *extremely* small but non-zero chance that that
>> -	 * multiple threads could get in here, and one thread could
>> -	 * be scanning through the list of bits looking for a free
>> -	 * one, but the free ones are always behind him, and other
>> -	 * threads sneak in behind him and eat them before he can
>> -	 * get to them, so that while there is always a free one, a
>> -	 * very unlucky thread might be starved anyway, never able to
>> -	 * beat the other threads.  In reality, this happens so
>> -	 * infrequently as to be indistinguishable from never.
>> -	 *
>> -	 * Note that we start allocating commands before the SCSI host structure
>> -	 * is initialized.  Since the search starts at bit zero, this
>> -	 * all works, since we have at least one command structure available;
>> -	 * however, it means that the structures with the low indexes have to be
>> -	 * reserved for driver-initiated requests, while requests from the block
>> -	 * layer will use the higher indexes.
>> -	 */
>> -
>> -	for (;;) {
>> -		i = find_next_zero_bit(h->cmd_pool_bits,
>> -					HPSA_NRESERVED_CMDS,
>> -					offset);
>> -		if (unlikely(i >= HPSA_NRESERVED_CMDS)) {
>> -			offset = 0;
>> -			continue;
>> -		}
>> -		c = h->cmd_pool + i;
>> -		refcount = atomic_inc_return(&c->refcount);
>> -		if (unlikely(refcount > 1)) {
>> -			cmd_free(h, c); /* already in use */
>> -			offset = (i + 1) % HPSA_NRESERVED_CMDS;
>> -			continue;
>> -		}
>> -		set_bit(i & (BITS_PER_LONG - 1),
>> -			h->cmd_pool_bits + (i / BITS_PER_LONG));
>> -		break; /* it's ours now. */
>> +	int idx;
>> +
>> +	scmd = scsi_get_internal_cmd(h->raid_ctrl_sdev,
>> +				     (direction & XFER_WRITE) ?
>> +				     DMA_TO_DEVICE : DMA_FROM_DEVICE,
>> +				     REQ_NOWAIT);
>> +	if (!scmd) {
>> +		dev_warn(&h->pdev->dev, "failed to allocate reserved cmd\n");
>> +		return NULL;
> 
> I think in the orig code cmd_alloc would always return a non null pointer.
> It looks like we would always just keep looping.
> 
> Now, it looks like we could fail from the above code where we return NULL.
> I was not sure if it's maybe impossible to hit the "return NULL" becuase we
> only call this function when we know there will be a cmd availale. If we
> can fail then the cmd_alloc callers should check for NULL now I think.
> 
Yes, that's indeed the case with this patch.
But seeing that the original code would spin until a tag becomes
available we can drop the REQ_NOWAIT flags and should get roughly the
same behaviour as we have now.

Will be updating the patch.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		           Kernel Storage Architect
hare@xxxxxxx			                  +49 911 74053 688
SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), GF: Felix Imendörffer



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux