From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 86C156CD5 for ; Tue, 14 Jun 2016 11:38:40 +0200 (CEST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga101.fm.intel.com with ESMTP; 14 Jun 2016 02:38:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,470,1459839600"; d="scan'208";a="121531881" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga004.fm.intel.com with ESMTP; 14 Jun 2016 02:38:32 -0700 Received: from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com [10.237.217.46]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id u5E9cVPP020237; Tue, 14 Jun 2016 10:38:31 +0100 Received: from sivswdev02.ir.intel.com (localhost [127.0.0.1]) by sivswdev02.ir.intel.com with ESMTP id u5E9cVlQ026603; Tue, 14 Jun 2016 10:38:31 +0100 Received: (from reshmapa@localhost) by sivswdev02.ir.intel.com with id u5E9cVVC026599; Tue, 14 Jun 2016 10:38:31 +0100 From: Reshma Pattan To: dev@dpdk.org Cc: Reshma Pattan Date: Tue, 14 Jun 2016 10:38:21 +0100 Message-Id: <1465897108-26548-2-git-send-email-reshma.pattan@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1465897108-26548-1-git-send-email-reshma.pattan@intel.com> References: <1465575534-23605-1-git-send-email-reshma.pattan@intel.com> <1465897108-26548-1-git-send-email-reshma.pattan@intel.com> Subject: [dpdk-dev] [PATCH v9 1/8] ethdev: use locks to protect Rx/Tx callback lists X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Jun 2016 09:38:41 -0000 Added spinlocks around add/remove logic of Rx and Tx callbacks to avoid corruption of callback lists in multithreaded context. Signed-off-by: Reshma Pattan --- lib/librte_ether/rte_ethdev.c | 82 +++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index e148028..ce70d58 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -77,6 +77,12 @@ static uint8_t nb_ports; /* spinlock for eth device callbacks */ static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER; +/* spinlock for add/remove rx callbacks */ +static rte_spinlock_t rte_eth_rx_cb_lock = RTE_SPINLOCK_INITIALIZER; + +/* spinlock for add/remove tx callbacks */ +static rte_spinlock_t rte_eth_tx_cb_lock = RTE_SPINLOCK_INITIALIZER; + /* store statistics names and its offset in stats structure */ struct rte_eth_xstats_name_off { char name[RTE_ETH_XSTATS_NAME_SIZE]; @@ -1634,7 +1640,6 @@ rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t rx_queue_id, STAT_QMAP_RX); } - void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info) { @@ -2905,7 +2910,6 @@ rte_eth_add_rx_callback(uint8_t port_id, uint16_t queue_id, rte_errno = EINVAL; return NULL; } - struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0); if (cb == NULL) { @@ -2916,6 +2920,7 @@ rte_eth_add_rx_callback(uint8_t port_id, uint16_t queue_id, cb->fn.rx = fn; cb->param = user_param; + rte_spinlock_lock(&rte_eth_rx_cb_lock); /* Add the callbacks in fifo order. */ struct rte_eth_rxtx_callback *tail = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; @@ -2928,6 +2933,7 @@ rte_eth_add_rx_callback(uint8_t port_id, uint16_t queue_id, tail = tail->next; tail->next = cb; } + rte_spinlock_unlock(&rte_eth_rx_cb_lock); return cb; } @@ -2957,6 +2963,7 @@ rte_eth_add_tx_callback(uint8_t port_id, uint16_t queue_id, cb->fn.tx = fn; cb->param = user_param; + rte_spinlock_lock(&rte_eth_tx_cb_lock); /* Add the callbacks in fifo order. */ struct rte_eth_rxtx_callback *tail = rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id]; @@ -2969,6 +2976,7 @@ rte_eth_add_tx_callback(uint8_t port_id, uint16_t queue_id, tail = tail->next; tail->next = cb; } + rte_spinlock_unlock(&rte_eth_tx_cb_lock); return cb; } @@ -2987,29 +2995,24 @@ rte_eth_remove_rx_callback(uint8_t port_id, uint16_t queue_id, return -EINVAL; struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - struct rte_eth_rxtx_callback *cb = dev->post_rx_burst_cbs[queue_id]; - struct rte_eth_rxtx_callback *prev_cb; - - /* Reset head pointer and remove user cb if first in the list. */ - if (cb == user_cb) { - dev->post_rx_burst_cbs[queue_id] = user_cb->next; - return 0; - } - - /* Remove the user cb from the callback list. */ - do { - prev_cb = cb; - cb = cb->next; - + struct rte_eth_rxtx_callback *cb; + struct rte_eth_rxtx_callback **prev_cb; + int ret = -EINVAL; + + rte_spinlock_lock(&rte_eth_rx_cb_lock); + prev_cb = &dev->post_rx_burst_cbs[queue_id]; + for (; *prev_cb != NULL; prev_cb = &cb->next) { + cb = *prev_cb; if (cb == user_cb) { - prev_cb->next = user_cb->next; - return 0; + /* Remove the user cb from the callback list. */ + *prev_cb = cb->next; + ret = 0; + break; } + } + rte_spinlock_unlock(&rte_eth_rx_cb_lock); - } while (cb != NULL); - - /* Callback wasn't found. */ - return -EINVAL; + return ret; } int @@ -3026,29 +3029,24 @@ rte_eth_remove_tx_callback(uint8_t port_id, uint16_t queue_id, return -EINVAL; struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - struct rte_eth_rxtx_callback *cb = dev->pre_tx_burst_cbs[queue_id]; - struct rte_eth_rxtx_callback *prev_cb; - - /* Reset head pointer and remove user cb if first in the list. */ - if (cb == user_cb) { - dev->pre_tx_burst_cbs[queue_id] = user_cb->next; - return 0; - } - - /* Remove the user cb from the callback list. */ - do { - prev_cb = cb; - cb = cb->next; - + int ret = -EINVAL; + struct rte_eth_rxtx_callback *cb; + struct rte_eth_rxtx_callback **prev_cb; + + rte_spinlock_lock(&rte_eth_tx_cb_lock); + prev_cb = &dev->pre_tx_burst_cbs[queue_id]; + for (; *prev_cb != NULL; prev_cb = &cb->next) { + cb = *prev_cb; if (cb == user_cb) { - prev_cb->next = user_cb->next; - return 0; + /* Remove the user cb from the callback list. */ + *prev_cb = cb->next; + ret = 0; + break; } + } + rte_spinlock_unlock(&rte_eth_tx_cb_lock); - } while (cb != NULL); - - /* Callback wasn't found. */ - return -EINVAL; + return ret; } int -- 2.5.0