[SCSI] zfcp: Use unchained mode for small ct and els requests
The ELS ADISC and the GID_PN requests sent from zfcp fit into unchained FSF requests. Change the FSF allocation logic to use unchained requests whenever possible where everything fits in one SBAL. This avoids acquiring more SBALs than necessary, especially during zfcp recovery when things might be stalled. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
688a1820bd
commit
426f6059b0
|
@ -1010,6 +1010,23 @@ skip_fsfstatus:
|
|||
send_ct->handler(send_ct->handler_data);
|
||||
}
|
||||
|
||||
static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale,
|
||||
struct scatterlist *sg_req,
|
||||
struct scatterlist *sg_resp)
|
||||
{
|
||||
sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
|
||||
sbale[2].addr = sg_virt(sg_req);
|
||||
sbale[2].length = sg_req->length;
|
||||
sbale[3].addr = sg_virt(sg_resp);
|
||||
sbale[3].length = sg_resp->length;
|
||||
sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
|
||||
}
|
||||
|
||||
static int zfcp_fsf_one_sbal(struct scatterlist *sg)
|
||||
{
|
||||
return sg_is_last(sg) && sg->length <= PAGE_SIZE;
|
||||
}
|
||||
|
||||
static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
|
||||
struct scatterlist *sg_req,
|
||||
struct scatterlist *sg_resp,
|
||||
|
@ -1020,16 +1037,16 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
|
|||
int bytes;
|
||||
|
||||
if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
|
||||
if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE ||
|
||||
!sg_is_last(sg_req) || !sg_is_last(sg_resp))
|
||||
if (!zfcp_fsf_one_sbal(sg_req) || !zfcp_fsf_one_sbal(sg_resp))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
|
||||
sbale[2].addr = sg_virt(sg_req);
|
||||
sbale[2].length = sg_req->length;
|
||||
sbale[3].addr = sg_virt(sg_resp);
|
||||
sbale[3].length = sg_resp->length;
|
||||
sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
|
||||
zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* use single, unchained SBAL if it can hold the request */
|
||||
if (zfcp_fsf_one_sbal(sg_req) && zfcp_fsf_one_sbal(sg_resp)) {
|
||||
zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue