On Tue, 30 Nov 2010 17:06:04 +0200 Alexander Nezhinsky <alexandern@xxxxxxxxxxxx> wrote: > When iscsi conn gets closed, some tasks may be still processed in scsi layer, > and can't be released immediatelly, thus their release is delayed. > But the conn release should be delayed too. To do this we can increment conn Why do we need this? iscsi_alloc_task calls conn_get() so as long as a task lives, its conn never be freed? > refcount per each task in scsi. Thus the last conn_put() in conn_close() will > not lead to the conn destruction. Then we decrement the refcount when the > tasks complete and ensure that the conn is freed when the last such task > returns from scsi. > > Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx> > --- > usr/iscsi/conn.c | 11 ++++++++++- > usr/iscsi/iscsid.c | 8 +++++++- > 2 files changed, 17 insertions(+), 2 deletions(-) > > diff --git a/usr/iscsi/conn.c b/usr/iscsi/conn.c > index a3af6a4..fa4096c 100644 > --- a/usr/iscsi/conn.c > +++ b/usr/iscsi/conn.c > @@ -173,8 +173,17 @@ void conn_close(struct iscsi_connection *conn) > * This task is in SCSI. We need to wait for I/O > * completion. > */ > - if (task_in_scsi(task)) > + if (task_in_scsi(task)) { > + /* We increment connection's refcount to allow > + * the task to complete in scsi layer. > + * Then we'll decrement it back and dispose of > + * the connection when no such tasks remain. > + */ > + dprintf("task %" PRIx64 " in_scsi, release delayed\n", > + task->tag); > + conn_get(conn); > continue; > + } > iscsi_free_task(task); > } > done: > diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c > index 3a79d93..050047e 100644 > --- a/usr/iscsi/iscsid.c > +++ b/usr/iscsi/iscsid.c > @@ -1184,9 +1184,15 @@ static int iscsi_scsi_cmd_done(uint64_t nid, int result, struct scsi_cmd *scmd) > * We could delay the closing of the conn in some cases and send > * the response with a little extra code or we can check if this > * task got reassinged to another connection. > + * When the connection was closing, its refcount got incremented > + * for each in_scsi task whose release was delayed. > + * Thus we need to decrement it back to enable proper > + * connection and session release. > */ > - if (task->conn->state == STATE_CLOSE) { > + if (task->conn->closed) { > + dprintf("task %" PRIx64 " from scsi, releasing\n", task->tag); > iscsi_free_cmd_task(task); > + conn_put(task->conn); > return 0; > } > > -- > 1.7.3.2 > -- > To unsubscribe from this list: send the line "unsubscribe stgt" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html