From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <hxie5@shecgisg003.sh.intel.com>
Received: from mga14.intel.com (mga14.intel.com [192.55.52.115])
 by dpdk.org (Postfix) with ESMTP id 6E344C422
 for <dev@dpdk.org>; Tue, 30 Jun 2015 11:21:02 +0200 (CEST)
Received: from fmsmga003.fm.intel.com ([10.253.24.29])
 by fmsmga103.fm.intel.com with ESMTP; 30 Jun 2015 02:21:02 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.15,376,1432623600"; d="scan'208";a="516477035"
Received: from shvmail01.sh.intel.com ([10.239.29.42])
 by FMSMGA003.fm.intel.com with ESMTP; 30 Jun 2015 02:21:00 -0700
Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com
 [10.239.29.90])
 by shvmail01.sh.intel.com with ESMTP id t5U9KvM1030304;
 Tue, 30 Jun 2015 17:20:57 +0800
Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1])
 by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id
 t5U9KsNP003593; Tue, 30 Jun 2015 17:20:56 +0800
Received: (from hxie5@localhost)
 by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t5U9KsOP003589;
 Tue, 30 Jun 2015 17:20:54 +0800
From: Huawei Xie <huawei.xie@intel.com>
To: dev@dpdk.org
Date: Tue, 30 Jun 2015 17:20:47 +0800
Message-Id: <1435656050-3539-2-git-send-email-huawei.xie@intel.com>
X-Mailer: git-send-email 1.7.4.1
In-Reply-To: <1435656050-3539-1-git-send-email-huawei.xie@intel.com>
References: <1434649260-26317-2-git-send-email-huawei.xie@intel.com>
 <1435656050-3539-1-git-send-email-huawei.xie@intel.com>
Subject: [dpdk-dev] [PATCH v4 1/4] vhost: call fdset_del_slot to remove
	connection fd
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: patches and discussions about DPDK <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Tue, 30 Jun 2015 09:21:04 -0000

In the event handler of connection fd, the connection fd could be possibly
closed. The event dispatch loop would then try to remove the fd from fdset.
Between these two actions, another thread might register a new listenfd
reusing the val of just closed fd, so we couldn't call fdset_del which would
wrongly clean up the new listenfd. A new function fdset_del_slot is provided
to cleanup the fd at the specified location.

v4 changes:
- call fdset_del_slot to remove connection fd

Signed-off-by: Huawei Xie <huawei.xie@intel.com>
---
 lib/librte_vhost/vhost_user/fd_man.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/lib/librte_vhost/vhost_user/fd_man.c b/lib/librte_vhost/vhost_user/fd_man.c
index 831c9c1..bd30f8d 100644
--- a/lib/librte_vhost/vhost_user/fd_man.c
+++ b/lib/librte_vhost/vhost_user/fd_man.c
@@ -188,6 +188,24 @@ fdset_del(struct fdset *pfdset, int fd)
 }
 
 /**
+ *  Unregister the fd at the specified slot from the fdset.
+ */
+static void
+fdset_del_slot(struct fdset *pfdset, int index)
+{
+	if (pfdset == NULL || index < 0 || index >= MAX_FDS)
+		return;
+
+	pthread_mutex_lock(&pfdset->fd_mutex);
+
+	pfdset->fd[index].fd = -1;
+	pfdset->fd[index].rcb = pfdset->fd[index].wcb = NULL;
+	pfdset->num--;
+
+	pthread_mutex_unlock(&pfdset->fd_mutex);
+}
+
+/**
  * This functions runs in infinite blocking loop until there is no fd in
  * pfdset. It calls corresponding r/w handler if there is event on the fd.
  *
@@ -248,8 +266,15 @@ fdset_event_dispatch(struct fdset *pfdset)
 			 * We don't allow fdset_del to be called in callback
 			 * directly.
 			 */
+			/*
+			 * When we are to clean up the fd from fdset,
+			 * because the fd is closed in the cb,
+			 * the old fd val could be reused by when creates new
+			 * listen fd in another thread, we couldn't call
+			 * fd_set_del.
+			 */
 			if (remove1 || remove2)
-				fdset_del(pfdset, fd);
+				fdset_del_slot(pfdset, i);
 		}
 	}
 }
-- 
1.8.1.4