From edbc9aa0580c0aca96ac8d11bfb2defa81d91bb3 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 13 May 2009 17:57:42 -0500 Subject: [SCSI] libiscsi: have iscsi_data_in_rsp call iscsi_update_cmdsn This has iscsi_data_in_rsp call iscsi_update_cmdsn when a pdu is completed like is done for other pdu's that are don. For libiscsi_tcp, this means that it calls iscsi_update_cmdsn when it is handling the pdu internally to only transfer data, but if there is status then it does not need to call it since the completion handling will do it. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi_tcp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/libiscsi_tcp.c') diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index b579ca9f4836..db93cd0dfdb6 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -473,7 +473,13 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task) int datasn = be32_to_cpu(rhdr->datasn); unsigned total_in_length = scsi_in(task->sc)->length; - iscsi_update_cmdsn(conn->session, (struct iscsi_nopin*)rhdr); + /* + * lib iscsi will update this in the completion handling if there + * is status. + */ + if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS)) + iscsi_update_cmdsn(conn->session, (struct iscsi_nopin*)rhdr); + if (tcp_conn->in.datalen == 0) return 0; -- cgit v1.2.1 From d1acfae514425d680912907c6554852f1e258551 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 13 May 2009 17:57:44 -0500 Subject: [SCSI] libiscsi_tcp: update recv tracking for each skb instead of iscsi pdu Everytime we read in a pdu libiscsi will update a tracking field. It uses this to decide when to check if the transport might be bad. If we have not got data in recv_timeout seconds then we will send a iscsi ping/nop. If we are on a slow link then it could take a while to read in all the data for a data_in. In that case we might send a ping/nop when we do not need to or we might drop a session thinking it is bad when the lower layer is making forward progress on it. This patch has libiscsi_tcp update the recv tracking for each skb (basically network packet from our point of view) instead of the entire iscsi pdu+data, so we account for these cases where data is coming in slowly. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi_tcp.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/scsi/libiscsi_tcp.c') diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index db93cd0dfdb6..b84a1d853f29 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -863,6 +863,12 @@ int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, int rc = 0; ISCSI_DBG_TCP(conn, "in %d bytes\n", skb->len - offset); + /* + * Update for each skb instead of pdu, because over slow networks a + * data_in's data could take a while to read in. We also want to + * account for r2ts. + */ + conn->last_recv = jiffies; if (unlikely(conn->suspend_rx)) { ISCSI_DBG_TCP(conn, "Rx suspended!\n"); -- cgit v1.2.1 From b3cd5050bf8eb32ceecee129cac7c59e6f1668c4 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 13 May 2009 17:57:49 -0500 Subject: [SCSI] libiscsi: add task aborted state If a task did not complete normally due to a TMF, libiscsi will now complete the task with the state ISCSI_TASK_ABRT_TMF. Drivers like bnx2i that need to free resources if a command did not complete normally can then check the task state. If a driver does not need to send a special command if we have dropped the session then they can check for ISCSI_TASK_ABRT_SESS_RECOV. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi_tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/libiscsi_tcp.c') diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index b84a1d853f29..2bc07090321d 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -440,8 +440,8 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task) struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_r2t_info *r2t; - /* nothing to do for mgmt or pending tasks */ - if (!task->sc || task->state == ISCSI_TASK_PENDING) + /* nothing to do for mgmt */ + if (!task->sc) return; /* flush task's r2t queues */ -- cgit v1.2.1