[ofa-general] [RFC PATCH] IB/srp: respect target credit limit

Roland Dreier rdreier at cisco.com
Mon Dec 17 21:58:17 PST 2007


 > The SRP initiator will currently send requests, even if we have no
 > credits available. The results of sending extra requests is
 > vendor-specific, but on some devices, overrunning our credits will cost
 > us 85% of peak performance -- e.g. 100 MB/s vs 720 MB/s. Other devices
 > may just drop them.

I guess this happens because a target sometimes completes commands
with a value of 0 for req_lim delta in the response?  Anyway, I didn't
realize this was a real problem in practice, but given that it is we
definitely want to fix it.  Your patch looks like the right idea
overall, but a few comments:

 > Also, it adds a queue length parameter to the target options, so that
 > the maximum number of commands the SCSI mid-layer will try to send can
 > be capped before it hits the credit limit.

Is there anything sensible someone can do with this new parameter?

 > +/* Must be called with target->scsi_host->host_lock held to protect
 > + * req_lim. Lock cannot be dropped between here and srp_use_credit().
 > + */
 > +static int srp_check_credit(struct srp_target_port *target,
 > +				enum srp_request_type req_type)
 > +{
 > +	/* Each request requires one credit, and we hold a credit in reserve
 > +	 * so that we can send task management requests.
 > +	 */
 > +	s32 min = (req_type == SRP_REQ_TASK_MGMT) ? 1 : 2;
 > +	return target->req_lim < min;
 > +}

It seems that things would be simpler if this test of credits went
into __srp_get_tx_iu() -- just have it return NULL if no credits are
available instead of bumping zero_req_lim.  And I guess add a
parameter to know whether the IU is for a task management command or
not.

 > +/* Must be called with target->scsi_host->host_lock held to protect
 > + * req_lim. Lock cannot be dropped between the call to srp_check_credit()
 > + * and the call to srp_use_credit()
 > + */
 > +static void srp_use_credit(struct srp_target_port *target)
 > +{
 > +	target->req_lim--;
 > +}

 > @@ -965,10 +987,8 @@ static int __srp_post_send(struct srp_target_port *target,
 > +	if (!ret)
 >  		++target->tx_head;
 > -		--target->req_lim;
 > -	}

Similarly I don't see anything gained aside from an opportunity for
incorrect code by moving the decrement of req_lim into its own
function that every caller of __srp_post_send() has to remember to
call right after __srp_post_send().

 > -			target->scsi_host->can_queue = min(target->req_lim,
 > -							   target->scsi_host->can_queue);

Why do we want to delete this?  It seems that for most sane targets,
the initial request limit in the login response is a good
approximation to what we should limit our queue depth to.

 > +	.max_host_blocked		= 1,

Documentation of what max_host_blocked does is pretty scant.  What
does this change do?

 - R.



More information about the general mailing list