From mboxrd@z Thu Jan 1 00:00:00 1970 From: Reshma Pattan Subject: [PATCH v4 1/9] librte_ether: protect add/remove of rxtx callbacks with spinlocks Date: Mon, 23 May 2016 22:38:24 +0100 Message-ID: <1464039512-2683-2-git-send-email-reshma.pattan@intel.com> References: <1463503030-10318-1-git-send-email-reshma.pattan@intel.com> <1464039512-2683-1-git-send-email-reshma.pattan@intel.com> Cc: Reshma Pattan To: dev@dpdk.org Return-path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id B6FA15A40 for ; Mon, 23 May 2016 23:42:29 +0200 (CEST) In-Reply-To: <1464039512-2683-1-git-send-email-reshma.pattan@intel.com> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Added spinlocks around add/remove logic of rxtx 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 a31018e..cf25d8a 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]; @@ -1639,7 +1645,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) { @@ -2925,7 +2930,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) { @@ -2936,6 +2940,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]; @@ -2948,6 +2953,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; } @@ -2977,6 +2983,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]; @@ -2989,6 +2996,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; } @@ -3007,29 +3015,24 @@ rte_eth_remove_rx_callback(uint8_t port_id, uint16_t queue_id, } 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 @@ -3046,29 +3049,24 @@ rte_eth_remove_tx_callback(uint8_t port_id, uint16_t queue_id, } 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