* [dpdk-dev] [RFC] ethdev: add IF-MIB attributes implementation @ 2017-07-13 14:48 Reshma Pattan 2017-07-13 16:24 ` [dpdk-dev] [RFC v2] " Reshma Pattan 0 siblings, 1 reply; 5+ messages in thread From: Reshma Pattan @ 2017-07-13 14:48 UTC (permalink / raw) To: dev; +Cc: Reshma Pattan The RFC shows implementation of IF-MIB attributes in ethdev layer. These attributes are implemeted from the information available from rte_eth_dev_data struct. The new APIs are added, to allow applications to trigger IF-MIB attribute initialization and the implementation based on the port id. IF-MIB attributes are allocated in shared memory to support multi process access. For not to expose IF-MIB attributes structs to user, the structs are kept internal. Making use of the metrics library to register attributes names to metrics library and update their values to metrics library by calling rte_metrics_reg_names() and rte_metrics_update_values() respectively. Applications should call rte_metrics_get_values() and rte_metrics_get_names() to view IF-MIB info. The above approach need, making ethdev librray dependent on metrics library. Is this acceptable? Comments are welcome. If not, we can move all the implementation to new library similar to bitarte and latency libraries. But the new library needs access to the rte_eth_dev_data. But AFAIK rte_eth_dev_data is not allowed to be accessed outside of PMDs and ethdev layer. Any comments here? Looking forward to hear opinions. Signed-off-by: Reshma Pattan <reshma.pattan@intel.com> --- lib/Makefile | 6 +- lib/librte_ether/rte_ethdev.c | 130 +++++++++++++++++++++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 7 ++ lib/librte_ether/rte_ethdev_pci.h | 4 ++ mk/rte.app.mk | 2 +- 5 files changed, 144 insertions(+), 5 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 07e1fd0..aa2be5b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -35,6 +35,8 @@ DIRS-y += librte_compat DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring DEPDIRS-librte_ring := librte_eal +DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics +DEPDIRS-librte_metrics := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool DEPDIRS-librte_mempool := librte_eal librte_ring DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf @@ -46,7 +48,7 @@ DEPDIRS-librte_cfgfile := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline DEPDIRS-librte_cmdline := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether -DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring +DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring librte_metrics DEPDIRS-librte_ether += librte_mbuf DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev DEPDIRS-librte_cryptodev := librte_eal librte_mempool librte_ring librte_mbuf @@ -70,8 +72,6 @@ DEPDIRS-librte_ip_frag := librte_eal librte_mempool librte_mbuf librte_ether DEPDIRS-librte_ip_frag += librte_hash DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += librte_jobstats DEPDIRS-librte_jobstats := librte_eal -DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics -DEPDIRS-librte_metrics := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += librte_bitratestats DEPDIRS-librte_bitratestats := librte_eal librte_metrics librte_ether DIRS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += librte_latencystats diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 71a576c..966b929 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -64,6 +64,8 @@ #include <rte_errno.h> #include <rte_spinlock.h> #include <rte_string_fns.h> +#include <rte_cycles.h> +#include <rte_metrics.h> #include "rte_ether.h" #include "rte_ethdev.h" @@ -118,7 +120,8 @@ static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = { #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \ sizeof(rte_txq_stats_strings[0])) - +#define RTE_MIB_ATTR_NAME_SIZE 32 +#define RTE_IF_TYPE_ETHERNETCSMACD 6 /** * The user application callback description. * @@ -139,6 +142,11 @@ enum { STAT_QMAP_RX }; +enum { + OPER_STATUS_UP = 1, + OPER_STATUS_DOWN +}; + uint8_t rte_eth_find_next(uint8_t port_id) { @@ -923,6 +931,8 @@ rte_eth_dev_start(uint8_t port_id) if (dev->data->dev_conf.intr_conf.lsc == 0) { RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); (*dev->dev_ops->link_update)(dev, 0); + dev->data->if_last_change = + rte_rdtsc() - dev->data->sys_up_time_start; } return 0; } @@ -1351,6 +1361,8 @@ rte_eth_stats_reset(uint8_t port_id) RTE_FUNC_PTR_OR_RET(*dev->dev_ops->stats_reset); (*dev->dev_ops->stats_reset)(dev); + dev->data->if_counter_discontinuity_time = + rte_rdtsc() - dev->data->sys_up_time_start; dev->data->rx_mbuf_alloc_failed = 0; } @@ -1829,6 +1841,8 @@ rte_eth_xstats_reset(uint8_t port_id) /* implemented by the driver */ if (dev->dev_ops->xstats_reset != NULL) { (*dev->dev_ops->xstats_reset)(dev); + dev->data->if_counter_discontinuity_time = + rte_rdtsc() - dev->data->sys_up_time_start; return; } @@ -3354,3 +3368,117 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id, -ENOTSUP); return (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en); } + +/* IF-MIB attributes*/ +struct rte_if_mib_attrs { + uint64_t if_number; /* ifNumber */ + uint64_t if_index; /* ifIndex */ + uint64_t if_type; /* ifType */ + uint64_t if_mtu; /* ifMtu */ + uint64_t if_speed; /* ifSpeed */ + uint64_t if_phys_address; /* ifPhysAddress */ + uint64_t if_oper_status; /* ifOperStatus */ + uint64_t if_last_change; /* ifLastChange */ + uint64_t if_high_speed; /* ifHighSpeed */ + uint64_t if_connector_present; /* ifConnectorPresent */ + uint64_t if_counter_discontinuity_time; /* ifCounterDiscontinuityTime */ +}; + +static struct rte_if_mib_attrs *if_mib_attrs; + +struct if_mib_attrs_nameoff { + char name[RTE_MIB_ATTR_NAME_SIZE]; + unsigned int offset; +}; + +static const struct if_mib_attrs_nameoff if_mib_attrs_strings[] = { + {"ifNumber", offsetof(struct rte_if_mib_attrs, if_number)}, + {"ifIndex", offsetof(struct rte_if_mib_attrs, if_index)}, + {"ifType", offsetof(struct rte_if_mib_attrs, if_type)}, + {"ifMtu", offsetof(struct rte_if_mib_attrs, if_mtu)}, + {"ifSpeed", offsetof(struct rte_if_mib_attrs, if_speed)}, + {"ifPhysAddress", offsetof(struct rte_if_mib_attrs, if_phys_address)}, + {"ifOperStatus", offsetof(struct rte_if_mib_attrs, if_oper_status)}, + {"ifLastChange", offsetof(struct rte_if_mib_attrs, if_last_change)}, + {"ifHighSpeed", offsetof(struct rte_if_mib_attrs, if_high_speed)}, + {"ifConnectorPresent", offsetof(struct rte_if_mib_attrs, + if_connector_present)}, + {"ifCounterDiscontinuityTime", offsetof(struct rte_if_mib_attrs, + if_counter_discontinuity_time)}, +}; + +#define NUM_IF_MIB_ATTRS (sizeof(if_mib_attrs_strings) / \ + sizeof(if_mib_attrs_strings[0])) + +int +rte_eth_ifmib_attr_init(void) { + if_mib_attrs = rte_zmalloc(NULL, sizeof(struct rte_if_mib_attrs), + RTE_CACHE_LINE_SIZE); + + return 0; +} + +int +rte_eth_ifmib_attr_reg(uint8_t port_id) { + + int idx; + unsigned int i; + uint64_t *attr_ptr = NULL; + const char *ptr_strings[NUM_IF_MIB_ATTRS] = {0}; + struct rte_eth_dev *eth_dev; + struct rte_device *device; + struct rte_eth_dev_data *data; + uint64_t values[NUM_IF_MIB_ATTRS] = {0}; + + for (i = 0; i < NUM_IF_MIB_ATTRS; i++) + ptr_strings[i] = if_mib_attrs_strings[i].name; + + /* register names with metrics library */ + idx = rte_metrics_reg_names(ptr_strings, NUM_IF_MIB_ATTRS); + + eth_dev = eth_dev_get(port_id); + data = eth_dev->data; + device = eth_dev->device; + + /* implement if mib attributes */ + if_mib_attrs->if_number = rte_eth_dev_count(); + + if_mib_attrs->if_index = data->port_id + 1; + + if_mib_attrs->if_type = RTE_IF_TYPE_ETHERNETCSMACD; + + if_mib_attrs->if_mtu = data->mtu; + + if_mib_attrs->if_speed = + (data->dev_link.link_speed < (UINT32_MAX / 1000000)) ? + (data->dev_link.link_speed * 1000000) : UINT32_MAX; + + if_mib_attrs->if_phys_address = 0; + ether_addr_copy(data->mac_addrs, + (struct ether_addr *)if_mib_attrs->if_phys_address); + + if_mib_attrs->if_oper_status = data->dev_link.link_status ? + OPER_STATUS_UP : OPER_STATUS_DOWN; + + if_mib_attrs->if_last_change = + data->if_last_change / (rte_get_tsc_hz() * 100); + + if_mib_attrs->if_high_speed = data->dev_link.link_speed; + + if_mib_attrs->if_connector_present = + (device->devargs->type == RTE_DEVTYPE_VIRTUAL) ? + OPER_STATUS_UP : OPER_STATUS_DOWN; + + if_mib_attrs->if_counter_discontinuity_time = + data->if_counter_discontinuity_time / (rte_get_tsc_hz() * 100); + + for (i = 0; i < NUM_IF_MIB_ATTRS; i++) { + attr_ptr = RTE_PTR_ADD(if_mib_attrs, + if_mib_attrs_strings[i].offset); + values[i] = *attr_ptr; + } + /* update values to metrics library */ + rte_metrics_update_values(port_id, idx, values, NUM_IF_MIB_ATTRS); + + return 0; +} diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 1446540..47c6cf6 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -1674,6 +1674,10 @@ struct rte_eth_dev_data { uint32_t dev_flags; /**< Capabilities */ enum rte_kernel_driver kdrv; /**< Kernel driver passthrough */ int numa_node; /**< NUMA node connection */ + /** IF-MIB attributes ifLastChange and ifCounterDiscontinuityTime */ + uint64_t sys_up_time_start; + uint64_t if_counter_discontinuity_time; + uint64_t if_last_change; }; /** Device supports hotplug detach */ @@ -4375,6 +4379,9 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id); int rte_eth_dev_get_name_by_port(uint8_t port_id, char *name); +int rte_eth_ifmib_attr_init(void); +int rte_eth_ifmib_attr_reg(uint8_t port_id); + #ifdef __cplusplus } #endif diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h index 69aab03..f829407 100644 --- a/lib/librte_ether/rte_ethdev_pci.h +++ b/lib/librte_ether/rte_ethdev_pci.h @@ -37,6 +37,7 @@ #include <rte_malloc.h> #include <rte_pci.h> #include <rte_ethdev.h> +#include <rte_cycles.h> /** * Copy pci device info to the Ethernet device data. @@ -157,6 +158,9 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev, RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL); ret = dev_init(eth_dev); + eth_dev->data->sys_up_time_start = rte_rdtsc(); + eth_dev->data->if_counter_discontinuity_time = 0; + eth_dev->data->if_last_change = 0; if (ret) rte_eth_dev_pci_release(eth_dev); diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 7d71a49..9dc9597 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -73,7 +73,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --no-whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats -_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics _LDLIBS-$(CONFIG_RTE_LIBRTE_BITRATE) += -lrte_bitratestats _LDLIBS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += -lrte_latencystats _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power @@ -95,6 +94,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += -lrte_eventdev _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING) += -lrte_mempool_ring _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring +_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder -- 2.7.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [RFC v2] ethdev: add IF-MIB attributes implementation 2017-07-13 14:48 [dpdk-dev] [RFC] ethdev: add IF-MIB attributes implementation Reshma Pattan @ 2017-07-13 16:24 ` Reshma Pattan 2017-07-14 0:07 ` Stephen Hemminger 2017-07-18 14:43 ` [dpdk-dev] [RFC v3] " Reshma Pattan 0 siblings, 2 replies; 5+ messages in thread From: Reshma Pattan @ 2017-07-13 16:24 UTC (permalink / raw) To: reshma.pattan, stephen, thomas, bruce.richardson, ferruh.yigit, radu.nicolau Cc: john.mcnamara, dev The RFC shows implementation of IF-MIB attributes in ethdev layer. These attributes are implemented from the information available from rte_eth_dev_data struct. The new APIs are added, to allow applications to trigger IF-MIB attribute initialization and the implementation based on the port id. IF-MIB attributes are allocated in shared memory to support multi process access. For not to expose IF-MIB attributes structs to user, the structs are kept internal. Making use of the metrics library to register attributes names to metrics library and update their values to metrics library by calling rte_metrics_reg_names() and rte_metrics_update_values() respectively. Applications should call rte_metrics_get_values() and rte_metrics_get_names() to view IF-MIB info. The above approach need, making ethdev librray dependent on metrics library. Is this acceptable? Comments are welcome. If not, we can move all the implementation to new library similar to bitrate and latency libraries. With this approach new library needs the access to rte_eth_devices[] to access rte_eth_dev_data. But AFAIK rte_eth_devices[] is not allowed to be accessed outside of PMDs and ethdev layer. Any comments here? Looking forward to hear opinions. Signed-off-by: Reshma Pattan <reshma.pattan@intel.com> --- v2: Corrected typos and description of the commit message. --- lib/Makefile | 6 +- lib/librte_ether/rte_ethdev.c | 130 +++++++++++++++++++++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 7 ++ lib/librte_ether/rte_ethdev_pci.h | 4 ++ mk/rte.app.mk | 2 +- 5 files changed, 144 insertions(+), 5 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 07e1fd0..aa2be5b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -35,6 +35,8 @@ DIRS-y += librte_compat DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring DEPDIRS-librte_ring := librte_eal +DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics +DEPDIRS-librte_metrics := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool DEPDIRS-librte_mempool := librte_eal librte_ring DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf @@ -46,7 +48,7 @@ DEPDIRS-librte_cfgfile := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline DEPDIRS-librte_cmdline := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether -DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring +DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring librte_metrics DEPDIRS-librte_ether += librte_mbuf DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev DEPDIRS-librte_cryptodev := librte_eal librte_mempool librte_ring librte_mbuf @@ -70,8 +72,6 @@ DEPDIRS-librte_ip_frag := librte_eal librte_mempool librte_mbuf librte_ether DEPDIRS-librte_ip_frag += librte_hash DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += librte_jobstats DEPDIRS-librte_jobstats := librte_eal -DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics -DEPDIRS-librte_metrics := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += librte_bitratestats DEPDIRS-librte_bitratestats := librte_eal librte_metrics librte_ether DIRS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += librte_latencystats diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 71a576c..966b929 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -64,6 +64,8 @@ #include <rte_errno.h> #include <rte_spinlock.h> #include <rte_string_fns.h> +#include <rte_cycles.h> +#include <rte_metrics.h> #include "rte_ether.h" #include "rte_ethdev.h" @@ -118,7 +120,8 @@ static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = { #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \ sizeof(rte_txq_stats_strings[0])) - +#define RTE_MIB_ATTR_NAME_SIZE 32 +#define RTE_IF_TYPE_ETHERNETCSMACD 6 /** * The user application callback description. * @@ -139,6 +142,11 @@ enum { STAT_QMAP_RX }; +enum { + OPER_STATUS_UP = 1, + OPER_STATUS_DOWN +}; + uint8_t rte_eth_find_next(uint8_t port_id) { @@ -923,6 +931,8 @@ rte_eth_dev_start(uint8_t port_id) if (dev->data->dev_conf.intr_conf.lsc == 0) { RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); (*dev->dev_ops->link_update)(dev, 0); + dev->data->if_last_change = + rte_rdtsc() - dev->data->sys_up_time_start; } return 0; } @@ -1351,6 +1361,8 @@ rte_eth_stats_reset(uint8_t port_id) RTE_FUNC_PTR_OR_RET(*dev->dev_ops->stats_reset); (*dev->dev_ops->stats_reset)(dev); + dev->data->if_counter_discontinuity_time = + rte_rdtsc() - dev->data->sys_up_time_start; dev->data->rx_mbuf_alloc_failed = 0; } @@ -1829,6 +1841,8 @@ rte_eth_xstats_reset(uint8_t port_id) /* implemented by the driver */ if (dev->dev_ops->xstats_reset != NULL) { (*dev->dev_ops->xstats_reset)(dev); + dev->data->if_counter_discontinuity_time = + rte_rdtsc() - dev->data->sys_up_time_start; return; } @@ -3354,3 +3368,117 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id, -ENOTSUP); return (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en); } + +/* IF-MIB attributes*/ +struct rte_if_mib_attrs { + uint64_t if_number; /* ifNumber */ + uint64_t if_index; /* ifIndex */ + uint64_t if_type; /* ifType */ + uint64_t if_mtu; /* ifMtu */ + uint64_t if_speed; /* ifSpeed */ + uint64_t if_phys_address; /* ifPhysAddress */ + uint64_t if_oper_status; /* ifOperStatus */ + uint64_t if_last_change; /* ifLastChange */ + uint64_t if_high_speed; /* ifHighSpeed */ + uint64_t if_connector_present; /* ifConnectorPresent */ + uint64_t if_counter_discontinuity_time; /* ifCounterDiscontinuityTime */ +}; + +static struct rte_if_mib_attrs *if_mib_attrs; + +struct if_mib_attrs_nameoff { + char name[RTE_MIB_ATTR_NAME_SIZE]; + unsigned int offset; +}; + +static const struct if_mib_attrs_nameoff if_mib_attrs_strings[] = { + {"ifNumber", offsetof(struct rte_if_mib_attrs, if_number)}, + {"ifIndex", offsetof(struct rte_if_mib_attrs, if_index)}, + {"ifType", offsetof(struct rte_if_mib_attrs, if_type)}, + {"ifMtu", offsetof(struct rte_if_mib_attrs, if_mtu)}, + {"ifSpeed", offsetof(struct rte_if_mib_attrs, if_speed)}, + {"ifPhysAddress", offsetof(struct rte_if_mib_attrs, if_phys_address)}, + {"ifOperStatus", offsetof(struct rte_if_mib_attrs, if_oper_status)}, + {"ifLastChange", offsetof(struct rte_if_mib_attrs, if_last_change)}, + {"ifHighSpeed", offsetof(struct rte_if_mib_attrs, if_high_speed)}, + {"ifConnectorPresent", offsetof(struct rte_if_mib_attrs, + if_connector_present)}, + {"ifCounterDiscontinuityTime", offsetof(struct rte_if_mib_attrs, + if_counter_discontinuity_time)}, +}; + +#define NUM_IF_MIB_ATTRS (sizeof(if_mib_attrs_strings) / \ + sizeof(if_mib_attrs_strings[0])) + +int +rte_eth_ifmib_attr_init(void) { + if_mib_attrs = rte_zmalloc(NULL, sizeof(struct rte_if_mib_attrs), + RTE_CACHE_LINE_SIZE); + + return 0; +} + +int +rte_eth_ifmib_attr_reg(uint8_t port_id) { + + int idx; + unsigned int i; + uint64_t *attr_ptr = NULL; + const char *ptr_strings[NUM_IF_MIB_ATTRS] = {0}; + struct rte_eth_dev *eth_dev; + struct rte_device *device; + struct rte_eth_dev_data *data; + uint64_t values[NUM_IF_MIB_ATTRS] = {0}; + + for (i = 0; i < NUM_IF_MIB_ATTRS; i++) + ptr_strings[i] = if_mib_attrs_strings[i].name; + + /* register names with metrics library */ + idx = rte_metrics_reg_names(ptr_strings, NUM_IF_MIB_ATTRS); + + eth_dev = eth_dev_get(port_id); + data = eth_dev->data; + device = eth_dev->device; + + /* implement if mib attributes */ + if_mib_attrs->if_number = rte_eth_dev_count(); + + if_mib_attrs->if_index = data->port_id + 1; + + if_mib_attrs->if_type = RTE_IF_TYPE_ETHERNETCSMACD; + + if_mib_attrs->if_mtu = data->mtu; + + if_mib_attrs->if_speed = + (data->dev_link.link_speed < (UINT32_MAX / 1000000)) ? + (data->dev_link.link_speed * 1000000) : UINT32_MAX; + + if_mib_attrs->if_phys_address = 0; + ether_addr_copy(data->mac_addrs, + (struct ether_addr *)if_mib_attrs->if_phys_address); + + if_mib_attrs->if_oper_status = data->dev_link.link_status ? + OPER_STATUS_UP : OPER_STATUS_DOWN; + + if_mib_attrs->if_last_change = + data->if_last_change / (rte_get_tsc_hz() * 100); + + if_mib_attrs->if_high_speed = data->dev_link.link_speed; + + if_mib_attrs->if_connector_present = + (device->devargs->type == RTE_DEVTYPE_VIRTUAL) ? + OPER_STATUS_UP : OPER_STATUS_DOWN; + + if_mib_attrs->if_counter_discontinuity_time = + data->if_counter_discontinuity_time / (rte_get_tsc_hz() * 100); + + for (i = 0; i < NUM_IF_MIB_ATTRS; i++) { + attr_ptr = RTE_PTR_ADD(if_mib_attrs, + if_mib_attrs_strings[i].offset); + values[i] = *attr_ptr; + } + /* update values to metrics library */ + rte_metrics_update_values(port_id, idx, values, NUM_IF_MIB_ATTRS); + + return 0; +} diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 1446540..47c6cf6 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -1674,6 +1674,10 @@ struct rte_eth_dev_data { uint32_t dev_flags; /**< Capabilities */ enum rte_kernel_driver kdrv; /**< Kernel driver passthrough */ int numa_node; /**< NUMA node connection */ + /** IF-MIB attributes ifLastChange and ifCounterDiscontinuityTime */ + uint64_t sys_up_time_start; + uint64_t if_counter_discontinuity_time; + uint64_t if_last_change; }; /** Device supports hotplug detach */ @@ -4375,6 +4379,9 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id); int rte_eth_dev_get_name_by_port(uint8_t port_id, char *name); +int rte_eth_ifmib_attr_init(void); +int rte_eth_ifmib_attr_reg(uint8_t port_id); + #ifdef __cplusplus } #endif diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h index 69aab03..f829407 100644 --- a/lib/librte_ether/rte_ethdev_pci.h +++ b/lib/librte_ether/rte_ethdev_pci.h @@ -37,6 +37,7 @@ #include <rte_malloc.h> #include <rte_pci.h> #include <rte_ethdev.h> +#include <rte_cycles.h> /** * Copy pci device info to the Ethernet device data. @@ -157,6 +158,9 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev, RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL); ret = dev_init(eth_dev); + eth_dev->data->sys_up_time_start = rte_rdtsc(); + eth_dev->data->if_counter_discontinuity_time = 0; + eth_dev->data->if_last_change = 0; if (ret) rte_eth_dev_pci_release(eth_dev); diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 7d71a49..9dc9597 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -73,7 +73,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --no-whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats -_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics _LDLIBS-$(CONFIG_RTE_LIBRTE_BITRATE) += -lrte_bitratestats _LDLIBS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += -lrte_latencystats _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power @@ -95,6 +94,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += -lrte_eventdev _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING) += -lrte_mempool_ring _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring +_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder -- 2.7.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [dpdk-dev] [RFC v2] ethdev: add IF-MIB attributes implementation 2017-07-13 16:24 ` [dpdk-dev] [RFC v2] " Reshma Pattan @ 2017-07-14 0:07 ` Stephen Hemminger 2017-07-14 9:33 ` Thomas Monjalon 2017-07-18 14:43 ` [dpdk-dev] [RFC v3] " Reshma Pattan 1 sibling, 1 reply; 5+ messages in thread From: Stephen Hemminger @ 2017-07-14 0:07 UTC (permalink / raw) To: Reshma Pattan Cc: thomas, bruce.richardson, ferruh.yigit, radu.nicolau, john.mcnamara, dev On Thu, 13 Jul 2017 17:24:27 +0100 Reshma Pattan <reshma.pattan@intel.com> wrote: > diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h > index 69aab03..f829407 100644 > --- a/lib/librte_ether/rte_ethdev_pci.h > +++ b/lib/librte_ether/rte_ethdev_pci.h > @@ -37,6 +37,7 @@ > #include <rte_malloc.h> > #include <rte_pci.h> > #include <rte_ethdev.h> > +#include <rte_cycles.h> > > /** > * Copy pci device info to the Ethernet device data. > @@ -157,6 +158,9 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev, > > RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL); > ret = dev_init(eth_dev); > + eth_dev->data->sys_up_time_start = rte_rdtsc(); > + eth_dev->data->if_counter_discontinuity_time = 0; > + eth_dev->data->if_last_change = 0; Shouldn't this be in base eth_dev layer rather than the PCI specific code. If you look in rte_eth_dev_data_alloc, the dev_data is already zeroed. Also, DPDK in general does BSD style structure names (ie always putting prefix on structure tags). In BSD, this is a leftover from ancient V6 UNIX where compiler did no real checking of structure tags. My preference is that variables and structure names be as short as possible. The TSC counter is not a good value to use on this anyway. You don't care about sub-microsecond accuracy and it wraps around. Better to figure out a better clock source. Is there a DPDK wrapper of clock_gettime(CLOCK_MONOTONIC)? ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [dpdk-dev] [RFC v2] ethdev: add IF-MIB attributes implementation 2017-07-14 0:07 ` Stephen Hemminger @ 2017-07-14 9:33 ` Thomas Monjalon 0 siblings, 0 replies; 5+ messages in thread From: Thomas Monjalon @ 2017-07-14 9:33 UTC (permalink / raw) To: Stephen Hemminger Cc: Reshma Pattan, bruce.richardson, ferruh.yigit, radu.nicolau, john.mcnamara, dev 14/07/2017 02:07, Stephen Hemminger: > On Thu, 13 Jul 2017 17:24:27 +0100 > Reshma Pattan <reshma.pattan@intel.com> wrote: > > > diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h > > index 69aab03..f829407 100644 > > --- a/lib/librte_ether/rte_ethdev_pci.h > > +++ b/lib/librte_ether/rte_ethdev_pci.h > > @@ -37,6 +37,7 @@ > > #include <rte_malloc.h> > > #include <rte_pci.h> > > #include <rte_ethdev.h> > > +#include <rte_cycles.h> > > > > /** > > * Copy pci device info to the Ethernet device data. > > @@ -157,6 +158,9 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev, > > > > RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL); > > ret = dev_init(eth_dev); > > + eth_dev->data->sys_up_time_start = rte_rdtsc(); > > + eth_dev->data->if_counter_discontinuity_time = 0; > > + eth_dev->data->if_last_change = 0; > > Shouldn't this be in base eth_dev layer rather than the PCI specific code. > > If you look in rte_eth_dev_data_alloc, the dev_data is already zeroed. > > Also, DPDK in general does BSD style structure names (ie always putting prefix > on structure tags). In BSD, this is a leftover from ancient V6 UNIX where > compiler did no real checking of structure tags. My preference is that > variables and structure names be as short as possible. > > The TSC counter is not a good value to use on this anyway. You don't care > about sub-microsecond accuracy and it wraps around. Better to figure out > a better clock source. Is there a DPDK wrapper of clock_gettime(CLOCK_MONOTONIC)? In rte_cycles.h, the TSC is wrapped into rte_get_timer_cycles(). About clock_gettime(CLOCK_MONOTONIC), I think we may need to create a file rte_clock.h. ^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [RFC v3] ethdev: add IF-MIB attributes implementation 2017-07-13 16:24 ` [dpdk-dev] [RFC v2] " Reshma Pattan 2017-07-14 0:07 ` Stephen Hemminger @ 2017-07-18 14:43 ` Reshma Pattan 1 sibling, 0 replies; 5+ messages in thread From: Reshma Pattan @ 2017-07-18 14:43 UTC (permalink / raw) To: stephen, thomas, bruce.richardson, ferruh.yigit, radu.nicolau Cc: john.mcnamara, dev, Reshma Pattan The RFC shows implementation of IF-MIB attributes in ethdev layer. These attributes are implemented from the information available from rte_eth_dev_data struct. The new APIs are added, to allow applications to trigger IF-MIB attribute initialization and the implementation based on the port id. IF-MIB attributes are allocated in shared memory to support multi process access. For not to expose IF-MIB attributes structs to user, the structs are kept internal. Making use of the metrics library to register attributes names to metrics library and update their values to metrics library by calling rte_metrics_reg_names() and rte_metrics_update_values() respectively. Applications should call rte_metrics_get_values() and rte_metrics_get_names() to view IF-MIB info. The above approach need, making ethdev librray dependent on metrics library. Is this acceptable? Comments are welcome. If not, we can move all the implementation to new library similar to bitrate and latency libraries. With this approach new library needs the access to rte_eth_devices[] to access rte_eth_dev_data. But AFAIK rte_eth_devices[] is not allowed to be accessed outside of PMDs and ethdev layer. Any comments here? Added rte_clock.h with wrapper function for clock_gettime(CLOCK_MONOTONIC). Question: Since ifLastChange and ifDiscontinuityTime IF-MIB attributes implementation should be based on the SysUpTime that is "The time since the network management portion of the system was last reinitialized". Since DPDK doesn't know about the the Network Management Portion, I assume these 2 attributes should not be implemented in DPDK. Please clarify. Looking forward to hear opinions. Signed-off-by: Reshma Pattan <reshma.pattan@intel.com> --- v3: *Added new file rte_clock.h to provide wrapper for clock_gettime(CLOCK_MONOTONIC). *Used new wrapper function to get the dev start time instead of TSC counter. *Renamed the new struct members. *Update the commit message. *Added a new question and seeking the clarification on the same. v2: Corrected typos and description of the commit message. --- lib/Makefile | 6 +- lib/librte_eal/common/Makefile | 2 +- lib/librte_eal/common/include/rte_clock.h | 68 ++++++++++++ lib/librte_ether/rte_ethdev.c | 172 +++++++++++++++++++++++++++++- lib/librte_ether/rte_ethdev.h | 7 ++ lib/librte_ether/rte_ethdev_pci.h | 1 + mk/rte.app.mk | 2 +- 7 files changed, 252 insertions(+), 6 deletions(-) create mode 100644 lib/librte_eal/common/include/rte_clock.h diff --git a/lib/Makefile b/lib/Makefile index 07e1fd0..aa2be5b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -35,6 +35,8 @@ DIRS-y += librte_compat DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring DEPDIRS-librte_ring := librte_eal +DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics +DEPDIRS-librte_metrics := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool DEPDIRS-librte_mempool := librte_eal librte_ring DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf @@ -46,7 +48,7 @@ DEPDIRS-librte_cfgfile := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline DEPDIRS-librte_cmdline := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether -DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring +DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring librte_metrics DEPDIRS-librte_ether += librte_mbuf DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev DEPDIRS-librte_cryptodev := librte_eal librte_mempool librte_ring librte_mbuf @@ -70,8 +72,6 @@ DEPDIRS-librte_ip_frag := librte_eal librte_mempool librte_mbuf librte_ether DEPDIRS-librte_ip_frag += librte_hash DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += librte_jobstats DEPDIRS-librte_jobstats := librte_eal -DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics -DEPDIRS-librte_metrics := librte_eal DIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += librte_bitratestats DEPDIRS-librte_bitratestats := librte_eal librte_metrics librte_ether DIRS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += librte_latencystats diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile index a5bd108..8dd438a 100644 --- a/lib/librte_eal/common/Makefile +++ b/lib/librte_eal/common/Makefile @@ -40,7 +40,7 @@ INC += rte_string_fns.h rte_version.h INC += rte_eal_memconfig.h rte_malloc_heap.h INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h -INC += rte_malloc.h rte_keepalive.h rte_time.h +INC += rte_malloc.h rte_keepalive.h rte_time.h rte_clock.h GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h diff --git a/lib/librte_eal/common/include/rte_clock.h b/lib/librte_eal/common/include/rte_clock.h new file mode 100644 index 0000000..8b22a37 --- /dev/null +++ b/lib/librte_eal/common/include/rte_clock.h @@ -0,0 +1,68 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017-2018 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_CLOCK_H_ +#define _RTE_CLOCK_H_ + +/** + * @file + * + * Retrieves the time of the monotonic clock. + */ +#include <time.h> + +struct rte_timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; + +/** + * Gets the time of the monotonic clock. + * + * @return + * The number of cycles + */ +static int +rte_clock_monotonic_gettime(struct rte_timespec *time) +{ + if (time == NULL) + return -1; + + struct timespec *sp = (struct timespec *)time; + if (clock_gettime(CLOCK_MONOTONIC, sp) != 0) + return -1; + + return 0; +} + +#endif /* _RTE_CLOCK_H_ */ diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 71a576c..14581d0 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -64,6 +64,10 @@ #include <rte_errno.h> #include <rte_spinlock.h> #include <rte_string_fns.h> +#include <rte_cycles.h> +#include <rte_metrics.h> +#include <rte_clock.h> +#include <rte_time.h> #include "rte_ether.h" #include "rte_ethdev.h" @@ -118,7 +122,8 @@ static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = { #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \ sizeof(rte_txq_stats_strings[0])) - +#define RTE_MIB_ATTR_NAME_SIZE 32 +#define RTE_IF_TYPE_ETHERNETCSMACD 6 /** * The user application callback description. * @@ -139,6 +144,11 @@ enum { STAT_QMAP_RX }; +enum { + OPER_STATUS_UP = 1, + OPER_STATUS_DOWN +}; + uint8_t rte_eth_find_next(uint8_t port_id) { @@ -218,6 +228,7 @@ rte_eth_dev_allocate(const char *name) { uint8_t port_id; struct rte_eth_dev *eth_dev; + struct rte_timespec tsp; port_id = rte_eth_dev_find_free_port(); if (port_id == RTE_MAX_ETHPORTS) { @@ -239,6 +250,13 @@ rte_eth_dev_allocate(const char *name) snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); eth_dev->data->port_id = port_id; eth_dev->data->mtu = ETHER_MTU; + if (rte_clock_monotonic_gettime(&tsp) != 0) { + RTE_PMD_DEBUG_TRACE("Failed to get monotonic clock time: " + "%s\n", __func__); + return NULL; + } + eth_dev->data->sys_up_time_start = + tsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec; return eth_dev; } @@ -898,6 +916,7 @@ rte_eth_dev_start(uint8_t port_id) { struct rte_eth_dev *dev; int diag; + struct rte_timespec tsp; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); @@ -923,6 +942,13 @@ rte_eth_dev_start(uint8_t port_id) if (dev->data->dev_conf.intr_conf.lsc == 0) { RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP); (*dev->dev_ops->link_update)(dev, 0); + if (rte_clock_monotonic_gettime(&tsp) != 0) { + RTE_PMD_DEBUG_TRACE("Failed to get monotonic clock time" + ": %s\n", __func__); + return -1; + } + dev->data->if_last_change = tsp.tv_sec * NSEC_PER_SEC + + tsp.tv_nsec - dev->data->sys_up_time_start; } return 0; } @@ -1295,6 +1321,7 @@ void rte_eth_link_get(uint8_t port_id, struct rte_eth_link *eth_link) { struct rte_eth_dev *dev; + struct rte_timespec tsp; RTE_ETH_VALID_PORTID_OR_RET(port_id); dev = &rte_eth_devices[port_id]; @@ -1305,6 +1332,12 @@ rte_eth_link_get(uint8_t port_id, struct rte_eth_link *eth_link) RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update); (*dev->dev_ops->link_update)(dev, 1); *eth_link = dev->data->dev_link; + + if (rte_clock_monotonic_gettime(&tsp) != 0) + RTE_PMD_DEBUG_TRACE("Failed to get monotonic clock time" + ": %s\n", __func__); + dev->data->if_last_change = tsp.tv_sec * NSEC_PER_SEC + + tsp.tv_nsec - dev->data->sys_up_time_start; } } @@ -1312,6 +1345,7 @@ void rte_eth_link_get_nowait(uint8_t port_id, struct rte_eth_link *eth_link) { struct rte_eth_dev *dev; + struct rte_timespec tsp; RTE_ETH_VALID_PORTID_OR_RET(port_id); dev = &rte_eth_devices[port_id]; @@ -1322,6 +1356,14 @@ rte_eth_link_get_nowait(uint8_t port_id, struct rte_eth_link *eth_link) RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update); (*dev->dev_ops->link_update)(dev, 0); *eth_link = dev->data->dev_link; + + if (rte_clock_monotonic_gettime(&tsp) != 0) { + RTE_PMD_DEBUG_TRACE("Failed to get monotonic clock time" + ": %s\n", __func__); + return -1; + } + dev->data->if_last_change = tsp.tv_sec * NSEC_PER_SEC + + tsp.tv_nsec - dev->data->sys_up_time_start; } } @@ -1345,12 +1387,20 @@ void rte_eth_stats_reset(uint8_t port_id) { struct rte_eth_dev *dev; + struct rte_timespec tsp; RTE_ETH_VALID_PORTID_OR_RET(port_id); dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_RET(*dev->dev_ops->stats_reset); (*dev->dev_ops->stats_reset)(dev); + + if (rte_clock_monotonic_gettime(&tsp) != 0) { + RTE_PMD_DEBUG_TRACE("Failed to get monotonic clock time: " + "%s\n", __func__); + } + dev->data->if_cntr_disc_time = tsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec - + dev->data->sys_up_time_start; dev->data->rx_mbuf_alloc_failed = 0; } @@ -1822,6 +1872,7 @@ void rte_eth_xstats_reset(uint8_t port_id) { struct rte_eth_dev *dev; + struct rte_timespec tsp; RTE_ETH_VALID_PORTID_OR_RET(port_id); dev = &rte_eth_devices[port_id]; @@ -1829,6 +1880,13 @@ rte_eth_xstats_reset(uint8_t port_id) /* implemented by the driver */ if (dev->dev_ops->xstats_reset != NULL) { (*dev->dev_ops->xstats_reset)(dev); + + if (rte_clock_monotonic_gettime(&tsp) != 0) + RTE_PMD_DEBUG_TRACE("Failed to get monotonic clock time: " + "%s\n", __func__); + dev->data->if_cntr_disc_time = tsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec - + dev->data->sys_up_time_start; + return; } @@ -3354,3 +3412,115 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id, -ENOTSUP); return (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en); } + +/* IF-MIB attributes*/ +struct rte_if_mib_attrs { + uint64_t if_number; /* ifNumber */ + uint64_t if_index; /* ifIndex */ + uint64_t if_type; /* ifType */ + uint64_t if_mtu; /* ifMtu */ + uint64_t if_speed; /* ifSpeed */ + uint64_t if_phys_address; /* ifPhysAddress */ + uint64_t if_oper_status; /* ifOperStatus */ + uint64_t if_last_change; /* ifLastChange */ + uint64_t if_high_speed; /* ifHighSpeed */ + uint64_t if_cnctr_present; /* ifConnectorPresent */ + uint64_t if_cntr_disc_time; /* ifCounterDiscontinuityTime */ +}; + +static struct rte_if_mib_attrs *if_mib_attrs; + +struct if_mib_attrs_nameoff { + char name[RTE_MIB_ATTR_NAME_SIZE]; + unsigned int offset; +}; + +static const struct if_mib_attrs_nameoff if_mib_attrs_strings[] = { + {"ifNumber", offsetof(struct rte_if_mib_attrs, if_number)}, + {"ifIndex", offsetof(struct rte_if_mib_attrs, if_index)}, + {"ifType", offsetof(struct rte_if_mib_attrs, if_type)}, + {"ifMtu", offsetof(struct rte_if_mib_attrs, if_mtu)}, + {"ifSpeed", offsetof(struct rte_if_mib_attrs, if_speed)}, + {"ifPhysAddress", offsetof(struct rte_if_mib_attrs, if_phys_address)}, + {"ifOperStatus", offsetof(struct rte_if_mib_attrs, if_oper_status)}, + {"ifLastChange", offsetof(struct rte_if_mib_attrs, if_last_change)}, + {"ifHighSpeed", offsetof(struct rte_if_mib_attrs, if_high_speed)}, + {"ifConnectorPresent", offsetof(struct rte_if_mib_attrs, + if_cnctr_present)}, + {"ifCounterDiscontinuityTime", offsetof(struct rte_if_mib_attrs, + if_cntr_disc_time)}, +}; + +#define NUM_IF_MIB_ATTRS (sizeof(if_mib_attrs_strings) / \ + sizeof(if_mib_attrs_strings[0])) + +int +rte_eth_ifmib_attr_init(void) { + if_mib_attrs = rte_zmalloc(NULL, sizeof(struct rte_if_mib_attrs), + RTE_CACHE_LINE_SIZE); + + return 0; +} + +int +rte_eth_ifmib_attr_reg(uint8_t port_id) { + + int idx; + unsigned int i; + uint64_t *attr_ptr = NULL; + const char *ptr_strings[NUM_IF_MIB_ATTRS] = {0}; + struct rte_eth_dev *eth_dev; + struct rte_device *device; + struct rte_eth_dev_data *data; + uint64_t values[NUM_IF_MIB_ATTRS] = {0}; + + for (i = 0; i < NUM_IF_MIB_ATTRS; i++) + ptr_strings[i] = if_mib_attrs_strings[i].name; + + /* register names with metrics library */ + idx = rte_metrics_reg_names(ptr_strings, NUM_IF_MIB_ATTRS); + + eth_dev = eth_dev_get(port_id); + data = eth_dev->data; + device = eth_dev->device; + + /* implement if mib attributes */ + if_mib_attrs->if_number = rte_eth_dev_count(); + + if_mib_attrs->if_index = data->port_id + 1; + + if_mib_attrs->if_type = RTE_IF_TYPE_ETHERNETCSMACD; + + if_mib_attrs->if_mtu = data->mtu; + + if_mib_attrs->if_speed = + (data->dev_link.link_speed < (UINT32_MAX / 1000000)) ? + (data->dev_link.link_speed * 1000000) : UINT32_MAX; + + if_mib_attrs->if_phys_address = 0; + ether_addr_copy(data->mac_addrs, + (struct ether_addr *)if_mib_attrs->if_phys_address); + + if_mib_attrs->if_oper_status = data->dev_link.link_status ? + OPER_STATUS_UP : OPER_STATUS_DOWN; + + if_mib_attrs->if_last_change = data->if_last_change; + + if_mib_attrs->if_high_speed = data->dev_link.link_speed; + + if_mib_attrs->if_cnctr_present = + (device->devargs->type == RTE_DEVTYPE_VIRTUAL) ? + OPER_STATUS_UP : OPER_STATUS_DOWN; + + if_mib_attrs->if_cntr_disc_time = data->if_cntr_disc_time; + + for (i = 0; i < NUM_IF_MIB_ATTRS; i++) { + attr_ptr = RTE_PTR_ADD(if_mib_attrs, + if_mib_attrs_strings[i].offset); + values[i] = *attr_ptr; + } + /* update values to metrics library */ + rte_metrics_update_values(port_id, idx, values, NUM_IF_MIB_ATTRS); + + return 0; +} diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 1446540..7ddbc41 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -1674,6 +1674,10 @@ struct rte_eth_dev_data { uint32_t dev_flags; /**< Capabilities */ enum rte_kernel_driver kdrv; /**< Kernel driver passthrough */ int numa_node; /**< NUMA node connection */ + /** IF-MIB attributes ifLastChange and ifCounterDiscontinuityTime */ + uint64_t sys_up_time_start; + uint64_t if_cntr_disc_time; + uint64_t if_last_change; }; /** Device supports hotplug detach */ @@ -4375,6 +4379,9 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id); int rte_eth_dev_get_name_by_port(uint8_t port_id, char *name); +int rte_eth_ifmib_attr_init(void); +int rte_eth_ifmib_attr_reg(uint8_t port_id); + #ifdef __cplusplus } #endif diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h index 69aab03..e6e757f 100644 --- a/lib/librte_ether/rte_ethdev_pci.h +++ b/lib/librte_ether/rte_ethdev_pci.h @@ -37,6 +37,7 @@ #include <rte_malloc.h> #include <rte_pci.h> #include <rte_ethdev.h> +#include <rte_cycles.h> /** * Copy pci device info to the Ethernet device data. diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 7d71a49..9dc9597 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -73,7 +73,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl _LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --no-whole-archive _LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats -_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics _LDLIBS-$(CONFIG_RTE_LIBRTE_BITRATE) += -lrte_bitratestats _LDLIBS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += -lrte_latencystats _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power @@ -95,6 +94,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += -lrte_eventdev _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING) += -lrte_mempool_ring _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring +_LDLIBS-$(CONFIG_RTE_LIBRTE_METRICS) += -lrte_metrics _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder -- 2.7.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-07-18 14:43 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-07-13 14:48 [dpdk-dev] [RFC] ethdev: add IF-MIB attributes implementation Reshma Pattan 2017-07-13 16:24 ` [dpdk-dev] [RFC v2] " Reshma Pattan 2017-07-14 0:07 ` Stephen Hemminger 2017-07-14 9:33 ` Thomas Monjalon 2017-07-18 14:43 ` [dpdk-dev] [RFC v3] " Reshma Pattan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).