Commit 2eefb20dbf3032da1ad111c1ce178f899bc4859a
Committed by
James Bottomley
1 parent
e37d2c4791
Exists in
master
and in
7 other branches
[SCSI] bnx2i: Fixed the TCP graceful termination initiation
In compliance to RFC793, a TCP graceful termination will be used instead of an abortive termination for the case where the remote has initiated the close of the connection. Additionally, a TCP abortive termination will be used to close the connection when a logout response is not received in time after a logout request has been initiated. Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Benjamin Li <benli@broadcom.com> Acked-by: Anil Veerabhadrappa <anilgv@broadcom.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Showing 3 changed files with 40 additions and 19 deletions Side-by-side Diff
drivers/scsi/bnx2i/bnx2i.h
... | ... | @@ -639,6 +639,8 @@ |
639 | 639 | EP_STATE_CLEANUP_CMPL = 0x800, |
640 | 640 | EP_STATE_TCP_FIN_RCVD = 0x1000, |
641 | 641 | EP_STATE_TCP_RST_RCVD = 0x2000, |
642 | + EP_STATE_LOGOUT_SENT = 0x4000, | |
643 | + EP_STATE_LOGOUT_RESP_RCVD = 0x8000, | |
642 | 644 | EP_STATE_PG_OFLD_FAILED = 0x1000000, |
643 | 645 | EP_STATE_ULP_UPDATE_FAILED = 0x2000000, |
644 | 646 | EP_STATE_CLEANUP_FAILED = 0x4000000, |
drivers/scsi/bnx2i/bnx2i_hwi.c
... | ... | @@ -562,6 +562,8 @@ |
562 | 562 | logout_wqe->num_bds = 1; |
563 | 563 | logout_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */ |
564 | 564 | |
565 | + bnx2i_conn->ep->state = EP_STATE_LOGOUT_SENT; | |
566 | + | |
565 | 567 | bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1); |
566 | 568 | return 0; |
567 | 569 | } |
... | ... | @@ -1482,6 +1484,8 @@ |
1482 | 1484 | resp_hdr->t2retain = cpu_to_be32(logout->time_to_retain); |
1483 | 1485 | |
1484 | 1486 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); |
1487 | + | |
1488 | + bnx2i_conn->ep->state = EP_STATE_LOGOUT_RESP_RCVD; | |
1485 | 1489 | done: |
1486 | 1490 | spin_unlock(&session->lock); |
1487 | 1491 | return 0; |
drivers/scsi/bnx2i/bnx2i_iscsi.c
... | ... | @@ -1890,6 +1890,8 @@ |
1890 | 1890 | case EP_STATE_ULP_UPDATE_START: |
1891 | 1891 | case EP_STATE_ULP_UPDATE_COMPL: |
1892 | 1892 | case EP_STATE_TCP_FIN_RCVD: |
1893 | + case EP_STATE_LOGOUT_SENT: | |
1894 | + case EP_STATE_LOGOUT_RESP_RCVD: | |
1893 | 1895 | case EP_STATE_ULP_UPDATE_FAILED: |
1894 | 1896 | ret = 1; |
1895 | 1897 | break; |
... | ... | @@ -1923,6 +1925,8 @@ |
1923 | 1925 | struct iscsi_session *session = NULL; |
1924 | 1926 | struct iscsi_conn *conn = NULL; |
1925 | 1927 | int ret = 0; |
1928 | + int close = 0; | |
1929 | + int close_ret = 0; | |
1926 | 1930 | |
1927 | 1931 | if (!hba) |
1928 | 1932 | return 0; |
1929 | 1933 | |
1930 | 1934 | |
... | ... | @@ -1939,32 +1943,43 @@ |
1939 | 1943 | session = conn->session; |
1940 | 1944 | } |
1941 | 1945 | |
1942 | - bnx2i_ep->state = EP_STATE_DISCONN_START; | |
1943 | - | |
1944 | 1946 | init_timer(&bnx2i_ep->ofld_timer); |
1945 | 1947 | bnx2i_ep->ofld_timer.expires = hba->conn_teardown_tmo + jiffies; |
1946 | 1948 | bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer; |
1947 | 1949 | bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep; |
1948 | 1950 | add_timer(&bnx2i_ep->ofld_timer); |
1949 | 1951 | |
1950 | - if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { | |
1951 | - int close = 0; | |
1952 | - int close_ret = 0; | |
1953 | - | |
1954 | - if (session) { | |
1955 | - spin_lock_bh(&session->lock); | |
1956 | - if (session->state == ISCSI_STATE_LOGGING_OUT) | |
1957 | - close = 1; | |
1958 | - spin_unlock_bh(&session->lock); | |
1959 | - } | |
1960 | - if (close) | |
1961 | - close_ret = cnic->cm_close(bnx2i_ep->cm_sk); | |
1962 | - else | |
1963 | - close_ret = cnic->cm_abort(bnx2i_ep->cm_sk); | |
1964 | - if (close_ret) | |
1965 | - bnx2i_ep->state = EP_STATE_DISCONN_COMPL; | |
1966 | - } else | |
1952 | + if (!test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) | |
1967 | 1953 | goto out; |
1954 | + | |
1955 | + if (session) { | |
1956 | + spin_lock_bh(&session->lock); | |
1957 | + if (bnx2i_ep->state != EP_STATE_TCP_FIN_RCVD) { | |
1958 | + if (session->state == ISCSI_STATE_LOGGING_OUT) { | |
1959 | + if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) { | |
1960 | + /* Logout sent, but no resp */ | |
1961 | + printk(KERN_ALERT "bnx2i - WARNING " | |
1962 | + "logout response was not " | |
1963 | + "received!\n"); | |
1964 | + } else if (bnx2i_ep->state == | |
1965 | + EP_STATE_LOGOUT_RESP_RCVD) | |
1966 | + close = 1; | |
1967 | + } | |
1968 | + } else | |
1969 | + close = 1; | |
1970 | + | |
1971 | + spin_unlock_bh(&session->lock); | |
1972 | + } | |
1973 | + | |
1974 | + bnx2i_ep->state = EP_STATE_DISCONN_START; | |
1975 | + | |
1976 | + if (close) | |
1977 | + close_ret = cnic->cm_close(bnx2i_ep->cm_sk); | |
1978 | + else | |
1979 | + close_ret = cnic->cm_abort(bnx2i_ep->cm_sk); | |
1980 | + | |
1981 | + if (close_ret) | |
1982 | + bnx2i_ep->state = EP_STATE_DISCONN_COMPL; | |
1968 | 1983 | |
1969 | 1984 | /* wait for option-2 conn teardown */ |
1970 | 1985 | wait_event_interruptible(bnx2i_ep->ofld_wait, |