pass(4): always retry CAM_REQUEUE_REQ ccbs

Matthew Jacob mj at feral.com
Wed Mar 10 15:40:20 UTC 2010


I think it's a good idea, but returning ERESTART directly would be a 
more seamless change.

> At present pass(4) never retries a request (or performs any other kind of error
> recovery) unless the request has CAM_PASS_ERR_RECOVER flag set.
> This gives applications a control over error checking and handling.
> But I think that in the case of CAM_REQUEUE_REQ status error recovery,
> specifically a request retry, should always be performed.
>
> Rationale:
> CAM_REQUEUE_REQ is really an internal flag/state in CAM subsystem.
> It doesn't convey any information about state of medium, device, bus, controller
> or the ccb itself.  Application can not make any meaningful differentiation
> based on this status.  It either should always retry a ccb with this status or
> face truly random failures.  As such, I haven't encountered so far any
> application that expects to get CAM_REQUEUE_REQ status.
> So I think that CAM_REQUEUE_REQ should be contained within the CAM and never be
> leaked to applications unless retry count is exhausted (to prevent endless loops
> in case of programming errors, primarily).
>
> What do you think?
> Do you see any reason not to do it?
>
> Here's a small patch that implements the behavior:
> --- a/sys/cam/scsi/scsi_pass.c
> +++ b/sys/cam/scsi/scsi_pass.c
> @@ -564,9 +564,8 @@ passsendccb
>   	 * error recovery.
>   	 */
>   	cam_periph_runccb(ccb,
> -	    (ccb->ccb_h.flags&  CAM_PASS_ERR_RECOVER) ? passerror : NULL,
> -	    /* cam_flags */ CAM_RETRY_SELTO, /* sense_flags */SF_RETRY_UA,
> -	    softc->device_stats);
> +	    passerror, /* cam_flags */ CAM_RETRY_SELTO,
> +	    /* sense_flags */SF_RETRY_UA, softc->device_stats);
>
>   	if (need_unmap != 0)
>   		cam_periph_unmapmem(ccb,&mapinfo);
> @@ -586,7 +585,10 @@ passerror
>
>   	periph = xpt_path_periph(ccb->ccb_h.path);
>   	softc = (struct pass_softc *)periph->softc;
> -	
> -	return(cam_periph_error(ccb, cam_flags, sense_flags,
> -				&softc->saved_ccb));
> +
> +	if ((ccb->ccb_h.flags&  CAM_PASS_ERR_RECOVER) != 0 ||
> +	 (ccb->ccb_h.status&  CAM_STATUS_MASK) == CAM_REQUEUE_REQ)
> +		return(cam_periph_error(ccb, cam_flags, sense_flags,
> +					&softc->saved_ccb));
> +	return(0);
>   }
>
>
> I am not sure, perhaps I could just explicitly return ERESTART in the case of
> CAM_REQUEUE_REQ instead of going through cam_periph_error?
>
>    



More information about the freebsd-scsi mailing list