X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_ev.c;h=f717faa7e7422aff64a127e786f79bd630db601b;hb=ed6e564c214e9852ff7f3d8f676a892dda905651;hp=af3c7b28139d3e2a018a5c3c4c2d0a80a4c3cbf9;hpb=4a18304d24c0939cbf552519428beb31053c6a05;p=dpdk.git diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c index af3c7b2813..f717faa7e7 100644 --- a/drivers/net/sfc/sfc_ev.c +++ b/drivers/net/sfc/sfc_ev.c @@ -40,6 +40,7 @@ #include "sfc_ev.h" #include "sfc_rx.h" #include "sfc_tx.h" +#include "sfc_kvargs.h" /* Initial delay when waiting for event queue init complete event */ @@ -103,7 +104,7 @@ sfc_ev_rx(void *arg, __rte_unused uint32_t label, uint32_t id, evq->exception = B_TRUE; sfc_err(evq->sa, "EVQ %u RxQ %u invalid RX abort " - "(id=%#x size=%u flags=%#x); needs restart\n", + "(id=%#x size=%u flags=%#x); needs restart", evq->evq_index, sfc_rxq_sw_index(rxq), id, size, flags); goto done; @@ -118,7 +119,7 @@ sfc_ev_rx(void *arg, __rte_unused uint32_t label, uint32_t id, sfc_err(evq->sa, "EVQ %u RxQ %u completion out of order " - "(id=%#x delta=%u flags=%#x); needs restart\n", + "(id=%#x delta=%u flags=%#x); needs restart", evq->evq_index, sfc_rxq_sw_index(rxq), id, delta, flags); @@ -286,11 +287,25 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode) struct sfc_adapter *sa = evq->sa; struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link; struct rte_eth_link new_link; + uint64_t new_link_u64; + uint64_t old_link_u64; EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t)); sfc_port_link_mode_to_info(link_mode, &new_link); - rte_atomic64_set((rte_atomic64_t *)dev_link, *(uint64_t *)&new_link); + + new_link_u64 = *(uint64_t *)&new_link; + do { + old_link_u64 = rte_atomic64_read((rte_atomic64_t *)dev_link); + if (old_link_u64 == new_link_u64) + break; + + if (rte_atomic64_cmpset((volatile uint64_t *)dev_link, + old_link_u64, new_link_u64)) { + evq->sa->port.lsc_seq++; + break; + } + } while (B_TRUE); return B_FALSE; } @@ -405,9 +420,7 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index) /* Create the common code event queue */ rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq_info->entries, - 0 /* unused on EF10 */, 0, - EFX_EVQ_FLAGS_TYPE_THROUGHPUT | - EFX_EVQ_FLAGS_NOTIFY_DISABLED, + 0 /* unused on EF10 */, 0, evq_info->flags, &evq->common); if (rc != 0) goto fail_ev_qcreate; @@ -486,10 +499,14 @@ sfc_ev_mgmt_periodic_qpoll(void *arg) rc = rte_eal_alarm_set(SFC_MGMT_EV_QPOLL_PERIOD_US, sfc_ev_mgmt_periodic_qpoll, sa); - if (rc != 0) - sfc_panic(sa, - "cannot rearm management EVQ polling alarm (rc=%d)", - rc); + if (rc == -ENOTSUP) { + sfc_warn(sa, "alarms are not supported"); + sfc_warn(sa, "management EVQ must be polled indirectly using no-wait link status update"); + } else if (rc != 0) { + sfc_err(sa, + "cannot rearm management EVQ polling alarm (rc=%d)", + rc); + } } static void @@ -522,6 +539,12 @@ sfc_ev_start(struct sfc_adapter *sa) 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); + if (rc != 0) + goto fail_evq0_prime; + } + rte_spinlock_unlock(&sa->mgmt_evq_lock); /* @@ -539,6 +562,9 @@ sfc_ev_start(struct sfc_adapter *sa) return 0; +fail_evq0_prime: + sfc_ev_qstop(sa, 0); + fail_mgmt_evq_start: rte_spinlock_unlock(&sa->mgmt_evq_lock); efx_ev_fini(sa->nic); @@ -640,6 +666,28 @@ sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index) SFC_ASSERT(rte_is_power_of_2(max_entries)); evq_info->max_entries = max_entries; + evq_info->flags = sa->evq_flags | + ((sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index) ? + EFX_EVQ_FLAGS_NOTIFY_INTERRUPT : + EFX_EVQ_FLAGS_NOTIFY_DISABLED); + + return 0; +} + +static int +sfc_kvarg_perf_profile_handler(__rte_unused const char *key, + const char *value_str, void *opaque) +{ + uint64_t *value = opaque; + + if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_THROUGHPUT) == 0) + *value = EFX_EVQ_FLAGS_TYPE_THROUGHPUT; + else if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_LOW_LATENCY) == 0) + *value = EFX_EVQ_FLAGS_TYPE_LOW_LATENCY; + else if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_AUTO) == 0) + *value = EFX_EVQ_FLAGS_TYPE_AUTO; + else + return -EINVAL; return 0; } @@ -660,6 +708,16 @@ sfc_ev_init(struct sfc_adapter *sa) sfc_log_init(sa, "entry"); + sa->evq_flags = EFX_EVQ_FLAGS_TYPE_THROUGHPUT; + rc = sfc_kvargs_process(sa, SFC_KVARG_PERF_PROFILE, + sfc_kvarg_perf_profile_handler, + &sa->evq_flags); + if (rc != 0) { + sfc_err(sa, "invalid %s parameter value", + SFC_KVARG_PERF_PROFILE); + goto fail_kvarg_perf_profile; + } + sa->evq_count = sfc_ev_qcount(sa); sa->mgmt_evq_index = 0; rte_spinlock_init(&sa->mgmt_evq_lock); @@ -700,6 +758,8 @@ fail_ev_qinit_info: fail_evqs_alloc: sa->evq_count = 0; + +fail_kvarg_perf_profile: sfc_log_init(sa, "failed %d", rc); return rc; }