From 6caeec474179a8337fc239dac3628c5e4ac84596 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Fri, 31 Mar 2017 11:22:16 +0100 Subject: [PATCH] net/sfc: remove EvQ info array to simplify reconfigure EvQ info array keeps information about EvQ centralized, however EvQ pointers are available in TxQ and RxQ structures. Single array for all EvQs complicates device reconfigure handling, so simply git rid of it. It removes notion of EvQ software index since there is no EvQ array in software any more. Fixes: 58294ee65afb ("net/sfc: support event queue") Fixes: 9a75f75cb1f2 ("net/sfc: maintain management event queue") Fixes: ce35b05c635e ("net/sfc: implement Rx queue setup release operations") Fixes: 28944ac098aa ("net/sfc: implement Rx queue start and stop operations") Fixes: b1b7ad933b39 ("net/sfc: set up and release Tx queues") Fixes: fed9aeb46c19 ("net/sfc: implement transmit path start / stop") Fixes: 3b809c27b1fe ("net/sfc: support link status change interrupt") Cc: stable@dpdk.org Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc.h | 3 +- drivers/net/sfc/sfc_ev.c | 146 ++++++++++--------------------------- drivers/net/sfc/sfc_ev.h | 31 +++----- drivers/net/sfc/sfc_intr.c | 2 +- drivers/net/sfc/sfc_rx.c | 23 +++--- drivers/net/sfc/sfc_tx.c | 21 +++--- 6 files changed, 70 insertions(+), 156 deletions(-) diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index e77639e15f..5fd734e635 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -139,7 +139,6 @@ struct sfc_intr { boolean_t lsc_intr; }; -struct sfc_evq_info; struct sfc_rxq_info; struct sfc_txq_info; struct sfc_dp_rx; @@ -204,10 +203,10 @@ struct sfc_adapter { uint32_t evq_flags; unsigned int evq_count; - struct sfc_evq_info *evq_info; unsigned int mgmt_evq_index; rte_spinlock_t mgmt_evq_lock; + struct sfc_evq *mgmt_evq; unsigned int rxq_count; struct sfc_rxq_info *rxq_info; diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c index bf108f1240..1432318ed4 100644 --- a/drivers/net/sfc/sfc_ev.c +++ b/drivers/net/sfc/sfc_ev.c @@ -566,7 +566,7 @@ void sfc_ev_mgmt_qpoll(struct sfc_adapter *sa) { if (rte_spinlock_trylock(&sa->mgmt_evq_lock)) { - struct sfc_evq *mgmt_evq = sa->evq_info[sa->mgmt_evq_index].evq; + struct sfc_evq *mgmt_evq = sa->mgmt_evq; if (mgmt_evq->init_state == SFC_EVQ_STARTED) sfc_ev_qpoll(mgmt_evq); @@ -582,33 +582,33 @@ sfc_ev_qprime(struct sfc_evq *evq) return efx_ev_qprime(evq->common, evq->read_ptr); } +/* Event queue HW index allocation scheme is described in sfc_ev.h. */ int -sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index) +sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index) { - const struct sfc_evq_info *evq_info; - struct sfc_evq *evq; + struct sfc_adapter *sa = evq->sa; efsys_mem_t *esmp; uint32_t evq_flags = sa->evq_flags; unsigned int total_delay_us; unsigned int delay_us; int rc; - sfc_log_init(sa, "sw_index=%u", sw_index); + sfc_log_init(sa, "hw_index=%u", hw_index); - evq_info = &sa->evq_info[sw_index]; - evq = evq_info->evq; esmp = &evq->mem; + evq->evq_index = hw_index; + /* Clear all events */ (void)memset((void *)esmp->esm_base, 0xff, EFX_EVQ_SIZE(evq->entries)); - if (sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index) + if (sa->intr.lsc_intr && hw_index == sa->mgmt_evq_index) evq_flags |= EFX_EVQ_FLAGS_NOTIFY_INTERRUPT; else evq_flags |= EFX_EVQ_FLAGS_NOTIFY_DISABLED; /* Create the common code event queue */ - rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq->entries, + rc = efx_ev_qcreate(sa->nic, hw_index, esmp, evq->entries, 0 /* unused on EF10 */, 0, evq_flags, &evq->common); if (rc != 0) @@ -671,19 +671,14 @@ fail_ev_qcreate: } void -sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index) +sfc_ev_qstop(struct sfc_evq *evq) { - const struct sfc_evq_info *evq_info; - struct sfc_evq *evq; - - sfc_log_init(sa, "sw_index=%u", sw_index); - - SFC_ASSERT(sw_index < sa->evq_count); + if (evq == NULL) + return; - evq_info = &sa->evq_info[sw_index]; - evq = evq_info->evq; + sfc_log_init(evq->sa, "hw_index=%u", evq->evq_index); - if (evq == NULL || evq->init_state != SFC_EVQ_STARTED) + if (evq->init_state != SFC_EVQ_STARTED) return; evq->init_state = SFC_EVQ_INITIALIZED; @@ -692,6 +687,8 @@ sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index) evq->exception = B_FALSE; efx_ev_qdestroy(evq->common); + + evq->evq_index = 0; } static void @@ -740,12 +737,12 @@ sfc_ev_start(struct sfc_adapter *sa) /* Start management EVQ used for global events */ rte_spinlock_lock(&sa->mgmt_evq_lock); - rc = sfc_ev_qstart(sa, sa->mgmt_evq_index); + rc = sfc_ev_qstart(sa->mgmt_evq, sa->mgmt_evq_index); if (rc != 0) goto fail_mgmt_evq_start; if (sa->intr.lsc_intr) { - rc = sfc_ev_qprime(sa->evq_info[sa->mgmt_evq_index].evq); + rc = sfc_ev_qprime(sa->mgmt_evq); if (rc != 0) goto fail_evq0_prime; } @@ -768,7 +765,7 @@ sfc_ev_start(struct sfc_adapter *sa) return 0; fail_evq0_prime: - sfc_ev_qstop(sa, 0); + sfc_ev_qstop(sa->mgmt_evq); fail_mgmt_evq_start: rte_spinlock_unlock(&sa->mgmt_evq_lock); @@ -782,41 +779,27 @@ fail_ev_init: void sfc_ev_stop(struct sfc_adapter *sa) { - unsigned int sw_index; - sfc_log_init(sa, "entry"); sfc_ev_mgmt_periodic_qpoll_stop(sa); - /* Make sure that all event queues are stopped */ - sw_index = sa->evq_count; - while (sw_index-- > 0) { - if (sw_index == sa->mgmt_evq_index) { - /* Locks are required for the management EVQ */ - rte_spinlock_lock(&sa->mgmt_evq_lock); - sfc_ev_qstop(sa, sa->mgmt_evq_index); - rte_spinlock_unlock(&sa->mgmt_evq_lock); - } else { - sfc_ev_qstop(sa, sw_index); - } - } + rte_spinlock_lock(&sa->mgmt_evq_lock); + sfc_ev_qstop(sa->mgmt_evq); + rte_spinlock_unlock(&sa->mgmt_evq_lock); efx_ev_fini(sa->nic); } int -sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index, +sfc_ev_qinit(struct sfc_adapter *sa, enum sfc_evq_type type, unsigned int type_index, - unsigned int entries, int socket_id) + unsigned int entries, int socket_id, struct sfc_evq **evqp) { - struct sfc_evq_info *evq_info; struct sfc_evq *evq; int rc; - sfc_log_init(sa, "sw_index=%u type=%s type_index=%u", - sw_index, sfc_evq_type2str(type), type_index); - - evq_info = &sa->evq_info[sw_index]; + sfc_log_init(sa, "type=%s type_index=%u", + sfc_evq_type2str(type), type_index); SFC_ASSERT(rte_is_power_of_2(entries)); @@ -827,7 +810,6 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index, goto fail_evq_alloc; evq->sa = sa; - evq->evq_index = sw_index; evq->type = type; evq->entries = entries; @@ -839,7 +821,9 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index, evq->init_state = SFC_EVQ_INITIALIZED; - evq_info->evq = evq; + sa->evq_count++; + + *evqp = evq; return 0; @@ -853,29 +837,18 @@ fail_evq_alloc: } void -sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index) +sfc_ev_qfini(struct sfc_evq *evq) { - struct sfc_evq *evq; - - sfc_log_init(sa, "sw_index=%u", sw_index); - - evq = sa->evq_info[sw_index].evq; + struct sfc_adapter *sa = evq->sa; SFC_ASSERT(evq->init_state == SFC_EVQ_INITIALIZED); - sa->evq_info[sw_index].evq = NULL; - sfc_dma_free(sa, &evq->mem); rte_free(evq); -} - -static int -sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index) -{ - sfc_log_init(sa, "sw_index=%u", sw_index); - return 0; + SFC_ASSERT(sa->evq_count > 0); + sa->evq_count--; } static int @@ -896,19 +869,10 @@ sfc_kvarg_perf_profile_handler(__rte_unused const char *key, return 0; } -static void -sfc_ev_qfini_info(struct sfc_adapter *sa, unsigned int sw_index) -{ - sfc_log_init(sa, "sw_index=%u", sw_index); - - /* Nothing to cleanup */ -} - int sfc_ev_init(struct sfc_adapter *sa) { int rc; - unsigned int sw_index; sfc_log_init(sa, "entry"); @@ -922,26 +886,11 @@ sfc_ev_init(struct sfc_adapter *sa) goto fail_kvarg_perf_profile; } - sa->evq_count = sfc_ev_qcount(sa); sa->mgmt_evq_index = 0; rte_spinlock_init(&sa->mgmt_evq_lock); - /* Allocate EVQ info array */ - rc = ENOMEM; - sa->evq_info = rte_calloc_socket("sfc-evqs", sa->evq_count, - sizeof(struct sfc_evq_info), 0, - sa->socket_id); - if (sa->evq_info == NULL) - goto fail_evqs_alloc; - - for (sw_index = 0; sw_index < sa->evq_count; ++sw_index) { - rc = sfc_ev_qinit_info(sa, sw_index); - if (rc != 0) - goto fail_ev_qinit_info; - } - - rc = sfc_ev_qinit(sa, sa->mgmt_evq_index, SFC_EVQ_TYPE_MGMT, 0, - SFC_MGMT_EVQ_ENTRIES, sa->socket_id); + rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_MGMT, 0, SFC_MGMT_EVQ_ENTRIES, + sa->socket_id, &sa->mgmt_evq); if (rc != 0) goto fail_mgmt_evq_init; @@ -953,15 +902,6 @@ sfc_ev_init(struct sfc_adapter *sa) return 0; fail_mgmt_evq_init: -fail_ev_qinit_info: - while (sw_index-- > 0) - sfc_ev_qfini_info(sa, sw_index); - - rte_free(sa->evq_info); - sa->evq_info = NULL; - -fail_evqs_alloc: - sa->evq_count = 0; fail_kvarg_perf_profile: sfc_log_init(sa, "failed %d", rc); @@ -971,19 +911,11 @@ fail_kvarg_perf_profile: void sfc_ev_fini(struct sfc_adapter *sa) { - int sw_index; - sfc_log_init(sa, "entry"); - /* Cleanup all event queues */ - sw_index = sa->evq_count; - while (--sw_index >= 0) { - if (sa->evq_info[sw_index].evq != NULL) - sfc_ev_qfini(sa, sw_index); - sfc_ev_qfini_info(sa, sw_index); - } + sfc_ev_qfini(sa->mgmt_evq); - rte_free(sa->evq_info); - sa->evq_info = NULL; - sa->evq_count = 0; + if (sa->evq_count != 0) + sfc_err(sa, "%u EvQs are not destroyed before detach", + sa->evq_count); } diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h index bc96213583..f73201b181 100644 --- a/drivers/net/sfc/sfc_ev.h +++ b/drivers/net/sfc/sfc_ev.h @@ -84,28 +84,15 @@ struct sfc_evq { unsigned int entries; }; -struct sfc_evq_info { - /* NUMA-aware EVQ data structure used on datapath */ - struct sfc_evq *evq; -}; - /* * Functions below define event queue to transmit/receive queue and vice * versa mapping. + * Own event queue is allocated for management, each Rx and each Tx queue. + * Zero event queue is used for management events. + * Rx event queues from 1 to RxQ number follow management event queue. + * Tx event queues follow Rx event queues. */ -static inline unsigned int -sfc_ev_qcount(struct sfc_adapter *sa) -{ - const struct rte_eth_dev_data *dev_data = sa->eth_dev->data; - - /* - * One management EVQ for global events. - * Own EVQ for each Tx and Rx queue. - */ - return 1 + dev_data->nb_rx_queues + dev_data->nb_tx_queues; -} - static inline unsigned int sfc_evq_index_by_rxq_sw_index(__rte_unused struct sfc_adapter *sa, unsigned int rxq_sw_index) @@ -124,12 +111,12 @@ void sfc_ev_fini(struct sfc_adapter *sa); int sfc_ev_start(struct sfc_adapter *sa); void sfc_ev_stop(struct sfc_adapter *sa); -int sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index, +int sfc_ev_qinit(struct sfc_adapter *sa, enum sfc_evq_type type, unsigned int type_index, - unsigned int entries, int socket_id); -void sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index); -int sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index); -void sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index); + unsigned int entries, int socket_id, struct sfc_evq **evqp); +void sfc_ev_qfini(struct sfc_evq *evq); +int sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index); +void sfc_ev_qstop(struct sfc_evq *evq); int sfc_ev_qprime(struct sfc_evq *evq); void sfc_ev_qpoll(struct sfc_evq *evq); diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c index 0d199b41b6..448709c1b1 100644 --- a/drivers/net/sfc/sfc_intr.c +++ b/drivers/net/sfc/sfc_intr.c @@ -55,7 +55,7 @@ sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa) rte_spinlock_lock(&sa->mgmt_evq_lock); - evq = sa->evq_info[sa->mgmt_evq_index].evq; + evq = sa->mgmt_evq; if (evq->init_state != SFC_EVQ_STARTED) { sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index); diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index bdaf21baaa..d8cd2286c7 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -642,7 +642,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index) evq = rxq->evq; - rc = sfc_ev_qstart(sa, evq->evq_index); + rc = sfc_ev_qstart(evq, sfc_evq_index_by_rxq_sw_index(sa, sw_index)); if (rc != 0) goto fail_ev_qstart; @@ -680,7 +680,7 @@ fail_dp_qstart: sfc_rx_qflush(sa, sw_index); fail_rx_qcreate: - sfc_ev_qstop(sa, evq->evq_index); + sfc_ev_qstop(evq); fail_ev_qstart: return rc; @@ -718,7 +718,7 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index) efx_rx_qdestroy(rxq->common); - sfc_ev_qstop(sa, rxq->evq->evq_index); + sfc_ev_qstop(rxq->evq); } static int @@ -861,7 +861,6 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, int rc; uint16_t buf_size; struct sfc_rxq_info *rxq_info; - unsigned int evq_index; struct sfc_evq *evq; struct sfc_rxq *rxq; struct sfc_dp_rx_qcreate_info info; @@ -899,15 +898,11 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, sa->eth_dev->data->dev_conf.rxmode.enable_scatter ? EFX_RXQ_TYPE_SCATTER : EFX_RXQ_TYPE_DEFAULT; - evq_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index); - - rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_RX, sw_index, - rxq_info->entries, socket_id); + rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index, + rxq_info->entries, socket_id, &evq); if (rc != 0) goto fail_ev_qinit; - evq = sa->evq_info[evq_index].evq; - rc = ENOMEM; rxq = rte_zmalloc_socket("sfc-rxq", sizeof(*rxq), RTE_CACHE_LINE_SIZE, socket_id); @@ -968,7 +963,7 @@ fail_dma_alloc: rte_free(rxq); fail_rxq_alloc: - sfc_ev_qfini(sa, evq_index); + sfc_ev_qfini(evq); fail_ev_qinit: rxq_info->entries = 0; @@ -998,9 +993,11 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index) rxq_info->entries = 0; sfc_dma_free(sa, &rxq->mem); - rte_free(rxq); - sfc_ev_qfini(sa, sfc_evq_index_by_rxq_sw_index(sa, sw_index)); + sfc_ev_qfini(rxq->evq); + rxq->evq = NULL; + + rte_free(rxq); } #if EFSYS_OPT_RX_SCALE diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c index 2c45e1aba9..9597029908 100644 --- a/drivers/net/sfc/sfc_tx.c +++ b/drivers/net/sfc/sfc_tx.c @@ -134,7 +134,6 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index, struct sfc_txq_info *txq_info; struct sfc_evq *evq; struct sfc_txq *txq; - unsigned int evq_index = sfc_evq_index_by_txq_sw_index(sa, sw_index); int rc = 0; struct sfc_dp_tx_qcreate_info info; @@ -150,13 +149,11 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index, SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries); txq_info->entries = nb_tx_desc; - rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_TX, sw_index, - txq_info->entries, socket_id); + rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_TX, sw_index, + txq_info->entries, socket_id, &evq); if (rc != 0) goto fail_ev_qinit; - evq = sa->evq_info[evq_index].evq; - rc = ENOMEM; txq = rte_zmalloc_socket("sfc-txq", sizeof(*txq), 0, socket_id); if (txq == NULL) @@ -209,7 +206,7 @@ fail_dma_alloc: rte_free(txq); fail_txq_alloc: - sfc_ev_qfini(sa, evq_index); + sfc_ev_qfini(evq); fail_ev_qinit: txq_info->entries = 0; @@ -241,9 +238,11 @@ sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index) txq_info->entries = 0; sfc_dma_free(sa, &txq->mem); - rte_free(txq); - sfc_ev_qfini(sa, sfc_evq_index_by_txq_sw_index(sa, sw_index)); + sfc_ev_qfini(txq->evq); + txq->evq = NULL; + + rte_free(txq); } static int @@ -379,7 +378,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index) evq = txq->evq; - rc = sfc_ev_qstart(sa, evq->evq_index); + rc = sfc_ev_qstart(evq, sfc_evq_index_by_txq_sw_index(sa, sw_index)); if (rc != 0) goto fail_ev_qstart; @@ -429,7 +428,7 @@ fail_dp_qstart: efx_tx_qdestroy(txq->common); fail_tx_qcreate: - sfc_ev_qstop(sa, evq->evq_index); + sfc_ev_qstop(evq); fail_ev_qstart: return rc; @@ -497,7 +496,7 @@ sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index) efx_tx_qdestroy(txq->common); - sfc_ev_qstop(sa, txq->evq->evq_index); + sfc_ev_qstop(txq->evq); /* * It seems to be used by DPDK for debug purposes only ('rte_ether') -- 2.20.1