scsi: target: iscsi: cxgbit: fix csk leak
csk leak can happen if a new TCP connection gets established after cxgbit_accept_np() returns, to fix this leak free remaining csk in cxgbit_free_np(). Signed-off-by: Varun Prakash <varun@chelsio.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
b90cd6f2b9
commit
801df68d61
|
@ -598,9 +598,12 @@ static void cxgbit_free_cdev_np(struct cxgbit_np *cnp)
|
||||||
mutex_unlock(&cdev_list_lock);
|
mutex_unlock(&cdev_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __cxgbit_free_conn(struct cxgbit_sock *csk);
|
||||||
|
|
||||||
void cxgbit_free_np(struct iscsi_np *np)
|
void cxgbit_free_np(struct iscsi_np *np)
|
||||||
{
|
{
|
||||||
struct cxgbit_np *cnp = np->np_context;
|
struct cxgbit_np *cnp = np->np_context;
|
||||||
|
struct cxgbit_sock *csk, *tmp;
|
||||||
|
|
||||||
cnp->com.state = CSK_STATE_DEAD;
|
cnp->com.state = CSK_STATE_DEAD;
|
||||||
if (cnp->com.cdev)
|
if (cnp->com.cdev)
|
||||||
|
@ -608,6 +611,13 @@ void cxgbit_free_np(struct iscsi_np *np)
|
||||||
else
|
else
|
||||||
cxgbit_free_all_np(cnp);
|
cxgbit_free_all_np(cnp);
|
||||||
|
|
||||||
|
spin_lock_bh(&cnp->np_accept_lock);
|
||||||
|
list_for_each_entry_safe(csk, tmp, &cnp->np_accept_list, accept_node) {
|
||||||
|
list_del_init(&csk->accept_node);
|
||||||
|
__cxgbit_free_conn(csk);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cnp->np_accept_lock);
|
||||||
|
|
||||||
np->np_context = NULL;
|
np->np_context = NULL;
|
||||||
cxgbit_put_cnp(cnp);
|
cxgbit_put_cnp(cnp);
|
||||||
}
|
}
|
||||||
|
@ -705,9 +715,9 @@ void cxgbit_abort_conn(struct cxgbit_sock *csk)
|
||||||
csk->tid, 600, __func__);
|
csk->tid, 600, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cxgbit_free_conn(struct iscsi_conn *conn)
|
static void __cxgbit_free_conn(struct cxgbit_sock *csk)
|
||||||
{
|
{
|
||||||
struct cxgbit_sock *csk = conn->context;
|
struct iscsi_conn *conn = csk->conn;
|
||||||
bool release = false;
|
bool release = false;
|
||||||
|
|
||||||
pr_debug("%s: state %d\n",
|
pr_debug("%s: state %d\n",
|
||||||
|
@ -716,7 +726,7 @@ void cxgbit_free_conn(struct iscsi_conn *conn)
|
||||||
spin_lock_bh(&csk->lock);
|
spin_lock_bh(&csk->lock);
|
||||||
switch (csk->com.state) {
|
switch (csk->com.state) {
|
||||||
case CSK_STATE_ESTABLISHED:
|
case CSK_STATE_ESTABLISHED:
|
||||||
if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
|
if (conn && (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT)) {
|
||||||
csk->com.state = CSK_STATE_CLOSING;
|
csk->com.state = CSK_STATE_CLOSING;
|
||||||
cxgbit_send_halfclose(csk);
|
cxgbit_send_halfclose(csk);
|
||||||
} else {
|
} else {
|
||||||
|
@ -741,6 +751,11 @@ void cxgbit_free_conn(struct iscsi_conn *conn)
|
||||||
cxgbit_put_csk(csk);
|
cxgbit_put_csk(csk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cxgbit_free_conn(struct iscsi_conn *conn)
|
||||||
|
{
|
||||||
|
__cxgbit_free_conn(conn->context);
|
||||||
|
}
|
||||||
|
|
||||||
static void cxgbit_set_emss(struct cxgbit_sock *csk, u16 opt)
|
static void cxgbit_set_emss(struct cxgbit_sock *csk, u16 opt)
|
||||||
{
|
{
|
||||||
csk->emss = csk->com.cdev->lldi.mtus[TCPOPT_MSS_G(opt)] -
|
csk->emss = csk->com.cdev->lldi.mtus[TCPOPT_MSS_G(opt)] -
|
||||||
|
@ -803,6 +818,7 @@ void _cxgbit_free_csk(struct kref *kref)
|
||||||
spin_unlock_bh(&cdev->cskq.lock);
|
spin_unlock_bh(&cdev->cskq.lock);
|
||||||
|
|
||||||
cxgbit_free_skb(csk);
|
cxgbit_free_skb(csk);
|
||||||
|
cxgbit_put_cnp(csk->cnp);
|
||||||
cxgbit_put_cdev(cdev);
|
cxgbit_put_cdev(cdev);
|
||||||
|
|
||||||
kfree(csk);
|
kfree(csk);
|
||||||
|
@ -1351,6 +1367,7 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb)
|
||||||
goto rel_skb;
|
goto rel_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cxgbit_get_cnp(cnp);
|
||||||
cxgbit_get_cdev(cdev);
|
cxgbit_get_cdev(cdev);
|
||||||
|
|
||||||
spin_lock(&cdev->cskq.lock);
|
spin_lock(&cdev->cskq.lock);
|
||||||
|
|
Loading…
Reference in New Issue