From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752043AbbINWmT (ORCPT ); Mon, 14 Sep 2015 18:42:19 -0400 Received: from linuxhacker.ru ([217.76.32.60]:44248 "EHLO fiona.linuxhacker.ru" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751848AbbINWmQ (ORCPT ); Mon, 14 Sep 2015 18:42:16 -0400 From: green@linuxhacker.ru To: Greg Kroah-Hartman , devel@driverdev.osuosl.org, Andreas Dilger Cc: Linux Kernel Mailing List , Liang Zhen , Oleg Drokin Subject: [PATCH 08/19] staging/lustre/o2iblnd: connection refcount fix for kiblnd_post_rx Date: Mon, 14 Sep 2015 18:41:24 -0400 Message-Id: <1442270495-1655259-9-git-send-email-green@linuxhacker.ru> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1442270495-1655259-1-git-send-email-green@linuxhacker.ru> References: <1442270495-1655259-1-git-send-email-green@linuxhacker.ru> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Liang Zhen kiblnd_post_rx() can't refer to rx::rx_conn anymore after ib_post_recv() because this rx can be polled out by another thread which may drop this rx and destroy rx::rx_conn. This patch fixes this issue by taking an extra refcount on connection before calling ib_post_recv(). Signed-off-by: Liang Zhen Reviewed-on: http://review.whamcloud.com/12852 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5678 Reviewed-by: Isaac Huang Reviewed-by: Amir Shehata Signed-off-by: Oleg Drokin --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 345ed4d..c0f5682 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -178,24 +178,28 @@ kiblnd_post_rx(kib_rx_t *rx, int credit) rx->rx_nob = -1; /* flag posted */ + /* NB: need an extra reference after ib_post_recv because we don't + * own this rx (and rx::rx_conn) anymore, LU-5678. + */ + kiblnd_conn_addref(conn); rc = ib_post_recv(conn->ibc_cmid->qp, &rx->rx_wrq, &bad_wrq); - if (rc != 0) { + if (unlikely(rc != 0)) { CERROR("Can't post rx for %s: %d, bad_wrq: %p\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), rc, bad_wrq); rx->rx_nob = 0; } if (conn->ibc_state < IBLND_CONN_ESTABLISHED) /* Initial post */ - return rc; + goto out; - if (rc != 0) { + if (unlikely(rc != 0)) { kiblnd_close_conn(conn, rc); kiblnd_drop_rx(rx); /* No more posts for this rx */ - return rc; + goto out; } if (credit == IBLND_POSTRX_NO_CREDIT) - return 0; + goto out; spin_lock(&conn->ibc_lock); if (credit == IBLND_POSTRX_PEER_CREDIT) @@ -205,7 +209,9 @@ kiblnd_post_rx(kib_rx_t *rx, int credit) spin_unlock(&conn->ibc_lock); kiblnd_check_sends(conn); - return 0; +out: + kiblnd_conn_decref(conn); + return rc; } static kib_tx_t * -- 2.1.0