net/sfc: add representors proxy infrastructure
Representor proxy is a mediator between virtual functions and port representors. It forwards traffic between virtual functions and port representors performing base PF ethdev + VF's representor traffic (de-)multiplexing. The implementation will be provided by later patches. Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru> Reviewed-by: Andy Moreton <amoreton@xilinx.com> Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
This commit is contained in:
parent
3f95dfb9c4
commit
52e80b1b64
@ -97,4 +97,5 @@ sources = files(
|
||||
'sfc_ef100_rx.c',
|
||||
'sfc_ef100_tx.c',
|
||||
'sfc_service.c',
|
||||
'sfc_repr_proxy.c',
|
||||
)
|
||||
|
@ -27,6 +27,25 @@
|
||||
#include "sfc_sw_stats.h"
|
||||
|
||||
|
||||
bool
|
||||
sfc_repr_supported(const struct sfc_adapter *sa)
|
||||
{
|
||||
if (!sa->switchdev)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Representor proxy should use service lcore on PF's socket
|
||||
* (sa->socket_id) to be efficient. But the proxy will fall back
|
||||
* to any socket if it is not possible to get the service core
|
||||
* on the same socket. Check that at least service core on any
|
||||
* socket is available.
|
||||
*/
|
||||
if (sfc_get_service_lcore(SOCKET_ID_ANY) == RTE_MAX_LCORE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
|
||||
size_t len, int socket_id, efsys_mem_t *esmp)
|
||||
@ -434,9 +453,16 @@ sfc_try_start(struct sfc_adapter *sa)
|
||||
if (rc != 0)
|
||||
goto fail_flows_insert;
|
||||
|
||||
rc = sfc_repr_proxy_start(sa);
|
||||
if (rc != 0)
|
||||
goto fail_repr_proxy_start;
|
||||
|
||||
sfc_log_init(sa, "done");
|
||||
return 0;
|
||||
|
||||
fail_repr_proxy_start:
|
||||
sfc_flow_stop(sa);
|
||||
|
||||
fail_flows_insert:
|
||||
sfc_tx_stop(sa);
|
||||
|
||||
@ -540,6 +566,7 @@ sfc_stop(struct sfc_adapter *sa)
|
||||
|
||||
sa->state = SFC_ADAPTER_STOPPING;
|
||||
|
||||
sfc_repr_proxy_stop(sa);
|
||||
sfc_flow_stop(sa);
|
||||
sfc_tx_stop(sa);
|
||||
sfc_rx_stop(sa);
|
||||
@ -899,6 +926,10 @@ sfc_attach(struct sfc_adapter *sa)
|
||||
if (rc != 0)
|
||||
goto fail_mae_switchdev_init;
|
||||
|
||||
rc = sfc_repr_proxy_attach(sa);
|
||||
if (rc != 0)
|
||||
goto fail_repr_proxy_attach;
|
||||
|
||||
sfc_log_init(sa, "fini nic");
|
||||
efx_nic_fini(enp);
|
||||
|
||||
@ -927,6 +958,9 @@ sfc_attach(struct sfc_adapter *sa)
|
||||
|
||||
fail_sw_xstats_init:
|
||||
sfc_flow_fini(sa);
|
||||
sfc_repr_proxy_detach(sa);
|
||||
|
||||
fail_repr_proxy_attach:
|
||||
sfc_mae_switchdev_fini(sa);
|
||||
|
||||
fail_mae_switchdev_init:
|
||||
@ -976,6 +1010,7 @@ sfc_detach(struct sfc_adapter *sa)
|
||||
|
||||
sfc_flow_fini(sa);
|
||||
|
||||
sfc_repr_proxy_detach(sa);
|
||||
sfc_mae_switchdev_fini(sa);
|
||||
sfc_mae_detach(sa);
|
||||
sfc_mae_counter_rxq_detach(sa);
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "sfc_mae.h"
|
||||
#include "sfc_dp.h"
|
||||
#include "sfc_sw_stats.h"
|
||||
#include "sfc_repr_proxy.h"
|
||||
#include "sfc_service.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -282,6 +284,7 @@ struct sfc_adapter {
|
||||
struct sfc_sw_stats sw_stats;
|
||||
struct sfc_filter filter;
|
||||
struct sfc_mae mae;
|
||||
struct sfc_repr_proxy repr_proxy;
|
||||
|
||||
struct sfc_flow_list flow_list;
|
||||
|
||||
@ -410,6 +413,8 @@ sfc_nb_counter_rxq(const struct sfc_adapter_shared *sas)
|
||||
return sas->counters_rxq_allocated ? 1 : 0;
|
||||
}
|
||||
|
||||
bool sfc_repr_supported(const struct sfc_adapter *sa);
|
||||
|
||||
/** Get the number of milliseconds since boot from the default timer */
|
||||
static inline uint64_t
|
||||
sfc_get_system_msecs(void)
|
||||
|
210
drivers/net/sfc/sfc_repr_proxy.c
Normal file
210
drivers/net/sfc/sfc_repr_proxy.c
Normal file
@ -0,0 +1,210 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright(c) 2019-2021 Xilinx, Inc.
|
||||
* Copyright(c) 2019 Solarflare Communications Inc.
|
||||
*
|
||||
* This software was jointly developed between OKTET Labs (under contract
|
||||
* for Solarflare) and Solarflare Communications, Inc.
|
||||
*/
|
||||
|
||||
#include <rte_service.h>
|
||||
#include <rte_service_component.h>
|
||||
|
||||
#include "sfc_log.h"
|
||||
#include "sfc_service.h"
|
||||
#include "sfc_repr_proxy.h"
|
||||
#include "sfc.h"
|
||||
|
||||
static int32_t
|
||||
sfc_repr_proxy_routine(void *arg)
|
||||
{
|
||||
struct sfc_repr_proxy *rp = arg;
|
||||
|
||||
/* Representor proxy boilerplate will be here */
|
||||
RTE_SET_USED(rp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sfc_repr_proxy_attach(struct sfc_adapter *sa)
|
||||
{
|
||||
struct sfc_repr_proxy *rp = &sa->repr_proxy;
|
||||
struct rte_service_spec service;
|
||||
uint32_t cid;
|
||||
uint32_t sid;
|
||||
int rc;
|
||||
|
||||
sfc_log_init(sa, "entry");
|
||||
|
||||
if (!sfc_repr_supported(sa)) {
|
||||
sfc_log_init(sa, "representors not supported - skip");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cid = sfc_get_service_lcore(sa->socket_id);
|
||||
if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) {
|
||||
/* Warn and try to allocate on any NUMA node */
|
||||
sfc_warn(sa,
|
||||
"repr proxy: unable to get service lcore at socket %d",
|
||||
sa->socket_id);
|
||||
|
||||
cid = sfc_get_service_lcore(SOCKET_ID_ANY);
|
||||
}
|
||||
if (cid == RTE_MAX_LCORE) {
|
||||
rc = ENOTSUP;
|
||||
sfc_err(sa, "repr proxy: failed to get service lcore");
|
||||
goto fail_get_service_lcore;
|
||||
}
|
||||
|
||||
memset(&service, 0, sizeof(service));
|
||||
snprintf(service.name, sizeof(service.name),
|
||||
"net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id);
|
||||
service.socket_id = rte_lcore_to_socket_id(cid);
|
||||
service.callback = sfc_repr_proxy_routine;
|
||||
service.callback_userdata = rp;
|
||||
|
||||
rc = rte_service_component_register(&service, &sid);
|
||||
if (rc != 0) {
|
||||
rc = ENOEXEC;
|
||||
sfc_err(sa, "repr proxy: failed to register service component");
|
||||
goto fail_register;
|
||||
}
|
||||
|
||||
rc = rte_service_map_lcore_set(sid, cid, 1);
|
||||
if (rc != 0) {
|
||||
rc = -rc;
|
||||
sfc_err(sa, "repr proxy: failed to map lcore");
|
||||
goto fail_map_lcore;
|
||||
}
|
||||
|
||||
rp->service_core_id = cid;
|
||||
rp->service_id = sid;
|
||||
|
||||
sfc_log_init(sa, "done");
|
||||
|
||||
return 0;
|
||||
|
||||
fail_map_lcore:
|
||||
rte_service_component_unregister(sid);
|
||||
|
||||
fail_register:
|
||||
/*
|
||||
* No need to rollback service lcore get since
|
||||
* it just makes socket_id based search and remembers it.
|
||||
*/
|
||||
|
||||
fail_get_service_lcore:
|
||||
sfc_log_init(sa, "failed: %s", rte_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
sfc_repr_proxy_detach(struct sfc_adapter *sa)
|
||||
{
|
||||
struct sfc_repr_proxy *rp = &sa->repr_proxy;
|
||||
|
||||
sfc_log_init(sa, "entry");
|
||||
|
||||
if (!sfc_repr_supported(sa)) {
|
||||
sfc_log_init(sa, "representors not supported - skip");
|
||||
return;
|
||||
}
|
||||
|
||||
rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0);
|
||||
rte_service_component_unregister(rp->service_id);
|
||||
|
||||
sfc_log_init(sa, "done");
|
||||
}
|
||||
|
||||
int
|
||||
sfc_repr_proxy_start(struct sfc_adapter *sa)
|
||||
{
|
||||
struct sfc_repr_proxy *rp = &sa->repr_proxy;
|
||||
int rc;
|
||||
|
||||
sfc_log_init(sa, "entry");
|
||||
|
||||
/*
|
||||
* The condition to start the proxy is insufficient. It will be
|
||||
* complemented with representor port start/stop support.
|
||||
*/
|
||||
if (!sfc_repr_supported(sa)) {
|
||||
sfc_log_init(sa, "representors not supported - skip");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Service core may be in "stopped" state, start it */
|
||||
rc = rte_service_lcore_start(rp->service_core_id);
|
||||
if (rc != 0 && rc != -EALREADY) {
|
||||
rc = -rc;
|
||||
sfc_err(sa, "failed to start service core for %s: %s",
|
||||
rte_service_get_name(rp->service_id),
|
||||
rte_strerror(rc));
|
||||
goto fail_start_core;
|
||||
}
|
||||
|
||||
/* Run the service */
|
||||
rc = rte_service_component_runstate_set(rp->service_id, 1);
|
||||
if (rc < 0) {
|
||||
rc = -rc;
|
||||
sfc_err(sa, "failed to run %s component: %s",
|
||||
rte_service_get_name(rp->service_id),
|
||||
rte_strerror(rc));
|
||||
goto fail_component_runstate_set;
|
||||
}
|
||||
rc = rte_service_runstate_set(rp->service_id, 1);
|
||||
if (rc < 0) {
|
||||
rc = -rc;
|
||||
sfc_err(sa, "failed to run %s: %s",
|
||||
rte_service_get_name(rp->service_id),
|
||||
rte_strerror(rc));
|
||||
goto fail_runstate_set;
|
||||
}
|
||||
|
||||
sfc_log_init(sa, "done");
|
||||
|
||||
return 0;
|
||||
|
||||
fail_runstate_set:
|
||||
rte_service_component_runstate_set(rp->service_id, 0);
|
||||
|
||||
fail_component_runstate_set:
|
||||
/* Service lcore may be shared and we never stop it */
|
||||
|
||||
fail_start_core:
|
||||
sfc_log_init(sa, "failed: %s", rte_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
sfc_repr_proxy_stop(struct sfc_adapter *sa)
|
||||
{
|
||||
struct sfc_repr_proxy *rp = &sa->repr_proxy;
|
||||
int rc;
|
||||
|
||||
sfc_log_init(sa, "entry");
|
||||
|
||||
if (!sfc_repr_supported(sa)) {
|
||||
sfc_log_init(sa, "representors not supported - skip");
|
||||
return;
|
||||
}
|
||||
|
||||
rc = rte_service_runstate_set(rp->service_id, 0);
|
||||
if (rc < 0) {
|
||||
sfc_err(sa, "failed to stop %s: %s",
|
||||
rte_service_get_name(rp->service_id),
|
||||
rte_strerror(-rc));
|
||||
}
|
||||
|
||||
rc = rte_service_component_runstate_set(rp->service_id, 0);
|
||||
if (rc < 0) {
|
||||
sfc_err(sa, "failed to stop %s component: %s",
|
||||
rte_service_get_name(rp->service_id),
|
||||
rte_strerror(-rc));
|
||||
}
|
||||
|
||||
/* Service lcore may be shared and we never stop it */
|
||||
|
||||
sfc_log_init(sa, "done");
|
||||
}
|
34
drivers/net/sfc/sfc_repr_proxy.h
Normal file
34
drivers/net/sfc/sfc_repr_proxy.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright(c) 2019-2021 Xilinx, Inc.
|
||||
* Copyright(c) 2019 Solarflare Communications Inc.
|
||||
*
|
||||
* This software was jointly developed between OKTET Labs (under contract
|
||||
* for Solarflare) and Solarflare Communications, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _SFC_REPR_PROXY_H
|
||||
#define _SFC_REPR_PROXY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct sfc_repr_proxy {
|
||||
uint32_t service_core_id;
|
||||
uint32_t service_id;
|
||||
};
|
||||
|
||||
struct sfc_adapter;
|
||||
|
||||
int sfc_repr_proxy_attach(struct sfc_adapter *sa);
|
||||
void sfc_repr_proxy_detach(struct sfc_adapter *sa);
|
||||
int sfc_repr_proxy_start(struct sfc_adapter *sa);
|
||||
void sfc_repr_proxy_stop(struct sfc_adapter *sa);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _SFC_REPR_PROXY_H */
|
Loading…
Reference in New Issue
Block a user