|
|
a6040a |
From 8f419225febbd2f02748fb142aab2c1b96fd3902 Mon Sep 17 00:00:00 2001
|
|
|
a6040a |
From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
|
|
|
a6040a |
Date: Wed, 7 Feb 2018 11:45:03 +0100
|
|
|
a6040a |
Subject: [PATCH 9/9] net/mlx: control netdevices through ioctl only
|
|
|
a6040a |
|
|
|
a6040a |
Several control operations implemented by these PMDs affect netdevices
|
|
|
a6040a |
through sysfs, itself subject to file system permission checks enforced by
|
|
|
a6040a |
the kernel, which limits their use for most purposes to applications
|
|
|
a6040a |
running with root privileges.
|
|
|
a6040a |
|
|
|
a6040a |
Since performing the same operations through ioctl() requires fewer
|
|
|
a6040a |
capabilities (only CAP_NET_ADMIN) and given the remaining operations are
|
|
|
a6040a |
already implemented this way, this patch standardizes on ioctl() and gets
|
|
|
a6040a |
rid of redundant code.
|
|
|
a6040a |
|
|
|
a6040a |
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
|
|
|
a6040a |
(cherry picked from commit 84c07af48024fc9d1027770e5143106e16ac49e7)
|
|
|
a6040a |
---
|
|
|
a6040a |
drivers/net/mlx4/mlx4_ethdev.c | 192 ++-----------------------------
|
|
|
a6040a |
drivers/net/mlx5/mlx5.h | 2 -
|
|
|
a6040a |
drivers/net/mlx5/mlx5_ethdev.c | 255 +++++------------------------------------
|
|
|
a6040a |
drivers/net/mlx5/mlx5_stats.c | 28 ++++-
|
|
|
a6040a |
4 files changed, 63 insertions(+), 414 deletions(-)
|
|
|
a6040a |
|
|
|
a6040a |
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
|
|
|
a6040a |
index e2f9509..cf7afe3 100644
|
|
|
a6040a |
--- a/drivers/net/mlx4/mlx4_ethdev.c
|
|
|
a6040a |
+++ b/drivers/net/mlx4/mlx4_ethdev.c
|
|
|
a6040a |
@@ -160,167 +160,6 @@
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/**
|
|
|
a6040a |
- * Read from sysfs entry.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param[in] priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] entry
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param[out] buf
|
|
|
a6040a |
- * Data output buffer.
|
|
|
a6040a |
- * @param size
|
|
|
a6040a |
- * Buffer size.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * Number of bytes read on success, negative errno value otherwise and
|
|
|
a6040a |
- * rte_errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-mlx4_sysfs_read(const struct priv *priv, const char *entry,
|
|
|
a6040a |
- char *buf, size_t size)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- char ifname[IF_NAMESIZE];
|
|
|
a6040a |
- FILE *file;
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
-
|
|
|
a6040a |
- ret = mlx4_get_ifname(priv, &ifname);
|
|
|
a6040a |
- if (ret)
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
-
|
|
|
a6040a |
- MKSTR(path, "%s/device/net/%s/%s", priv->ctx->device->ibdev_path,
|
|
|
a6040a |
- ifname, entry);
|
|
|
a6040a |
-
|
|
|
a6040a |
- file = fopen(path, "rb");
|
|
|
a6040a |
- if (file == NULL) {
|
|
|
a6040a |
- rte_errno = errno;
|
|
|
a6040a |
- return -rte_errno;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- ret = fread(buf, 1, size, file);
|
|
|
a6040a |
- if ((size_t)ret < size && ferror(file)) {
|
|
|
a6040a |
- rte_errno = EIO;
|
|
|
a6040a |
- ret = -rte_errno;
|
|
|
a6040a |
- } else {
|
|
|
a6040a |
- ret = size;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- fclose(file);
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Write to sysfs entry.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param[in] priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] entry
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param[in] buf
|
|
|
a6040a |
- * Data buffer.
|
|
|
a6040a |
- * @param size
|
|
|
a6040a |
- * Buffer size.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * Number of bytes written on success, negative errno value otherwise and
|
|
|
a6040a |
- * rte_errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-mlx4_sysfs_write(const struct priv *priv, const char *entry,
|
|
|
a6040a |
- char *buf, size_t size)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- char ifname[IF_NAMESIZE];
|
|
|
a6040a |
- FILE *file;
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
-
|
|
|
a6040a |
- ret = mlx4_get_ifname(priv, &ifname);
|
|
|
a6040a |
- if (ret)
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
-
|
|
|
a6040a |
- MKSTR(path, "%s/device/net/%s/%s", priv->ctx->device->ibdev_path,
|
|
|
a6040a |
- ifname, entry);
|
|
|
a6040a |
-
|
|
|
a6040a |
- file = fopen(path, "wb");
|
|
|
a6040a |
- if (file == NULL) {
|
|
|
a6040a |
- rte_errno = errno;
|
|
|
a6040a |
- return -rte_errno;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- ret = fwrite(buf, 1, size, file);
|
|
|
a6040a |
- if ((size_t)ret < size || ferror(file)) {
|
|
|
a6040a |
- rte_errno = EIO;
|
|
|
a6040a |
- ret = -rte_errno;
|
|
|
a6040a |
- } else {
|
|
|
a6040a |
- ret = size;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- fclose(file);
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Get unsigned long sysfs property.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] name
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param[out] value
|
|
|
a6040a |
- * Value output buffer.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 0 on success, negative errno value otherwise and rte_errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-mlx4_get_sysfs_ulong(struct priv *priv, const char *name, unsigned long *value)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
- unsigned long value_ret;
|
|
|
a6040a |
- char value_str[32];
|
|
|
a6040a |
-
|
|
|
a6040a |
- ret = mlx4_sysfs_read(priv, name, value_str, (sizeof(value_str) - 1));
|
|
|
a6040a |
- if (ret < 0) {
|
|
|
a6040a |
- DEBUG("cannot read %s value from sysfs: %s",
|
|
|
a6040a |
- name, strerror(rte_errno));
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- value_str[ret] = '\0';
|
|
|
a6040a |
- errno = 0;
|
|
|
a6040a |
- value_ret = strtoul(value_str, NULL, 0);
|
|
|
a6040a |
- if (errno) {
|
|
|
a6040a |
- rte_errno = errno;
|
|
|
a6040a |
- DEBUG("invalid %s value `%s': %s", name, value_str,
|
|
|
a6040a |
- strerror(rte_errno));
|
|
|
a6040a |
- return -rte_errno;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- *value = value_ret;
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Set unsigned long sysfs property.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] name
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param value
|
|
|
a6040a |
- * Value to set.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 0 on success, negative errno value otherwise and rte_errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-mlx4_set_sysfs_ulong(struct priv *priv, const char *name, unsigned long value)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
- MKSTR(value_str, "%lu", value);
|
|
|
a6040a |
-
|
|
|
a6040a |
- ret = mlx4_sysfs_write(priv, name, value_str, (sizeof(value_str) - 1));
|
|
|
a6040a |
- if (ret < 0) {
|
|
|
a6040a |
- DEBUG("cannot write %s `%s' (%lu) to sysfs: %s",
|
|
|
a6040a |
- name, value_str, value, strerror(rte_errno));
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
* Perform ifreq ioctl() on associated Ethernet device.
|
|
|
a6040a |
*
|
|
|
a6040a |
* @param[in] priv
|
|
|
a6040a |
@@ -389,12 +228,12 @@
|
|
|
a6040a |
int
|
|
|
a6040a |
mlx4_mtu_get(struct priv *priv, uint16_t *mtu)
|
|
|
a6040a |
{
|
|
|
a6040a |
- unsigned long ulong_mtu = 0;
|
|
|
a6040a |
- int ret = mlx4_get_sysfs_ulong(priv, "mtu", &ulong_mtu);
|
|
|
a6040a |
+ struct ifreq request;
|
|
|
a6040a |
+ int ret = mlx4_ifreq(priv, SIOCGIFMTU, &request);
|
|
|
a6040a |
|
|
|
a6040a |
if (ret)
|
|
|
a6040a |
return ret;
|
|
|
a6040a |
- *mtu = ulong_mtu;
|
|
|
a6040a |
+ *mtu = request.ifr_mtu;
|
|
|
a6040a |
return 0;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
@@ -413,20 +252,13 @@
|
|
|
a6040a |
mlx4_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
|
|
|
a6040a |
{
|
|
|
a6040a |
struct priv *priv = dev->data->dev_private;
|
|
|
a6040a |
- uint16_t new_mtu;
|
|
|
a6040a |
- int ret = mlx4_set_sysfs_ulong(priv, "mtu", mtu);
|
|
|
a6040a |
+ struct ifreq request = { .ifr_mtu = mtu, };
|
|
|
a6040a |
+ int ret = mlx4_ifreq(priv, SIOCSIFMTU, &request);
|
|
|
a6040a |
|
|
|
a6040a |
if (ret)
|
|
|
a6040a |
return ret;
|
|
|
a6040a |
- ret = mlx4_mtu_get(priv, &new_mtu);
|
|
|
a6040a |
- if (ret)
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
- if (new_mtu == mtu) {
|
|
|
a6040a |
- priv->mtu = mtu;
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- rte_errno = EINVAL;
|
|
|
a6040a |
- return -rte_errno;
|
|
|
a6040a |
+ priv->mtu = mtu;
|
|
|
a6040a |
+ return 0;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/**
|
|
|
a6040a |
@@ -445,14 +277,14 @@
|
|
|
a6040a |
static int
|
|
|
a6040a |
mlx4_set_flags(struct priv *priv, unsigned int keep, unsigned int flags)
|
|
|
a6040a |
{
|
|
|
a6040a |
- unsigned long tmp = 0;
|
|
|
a6040a |
- int ret = mlx4_get_sysfs_ulong(priv, "flags", &tmp);
|
|
|
a6040a |
+ struct ifreq request;
|
|
|
a6040a |
+ int ret = mlx4_ifreq(priv, SIOCGIFFLAGS, &request);
|
|
|
a6040a |
|
|
|
a6040a |
if (ret)
|
|
|
a6040a |
return ret;
|
|
|
a6040a |
- tmp &= keep;
|
|
|
a6040a |
- tmp |= (flags & (~keep));
|
|
|
a6040a |
- return mlx4_set_sysfs_ulong(priv, "flags", tmp);
|
|
|
a6040a |
+ request.ifr_flags &= keep;
|
|
|
a6040a |
+ request.ifr_flags |= flags & ~keep;
|
|
|
a6040a |
+ return mlx4_ifreq(priv, SIOCSIFFLAGS, &request);
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/**
|
|
|
a6040a |
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
|
|
|
a6040a |
index e6a69b8..a34121c 100644
|
|
|
a6040a |
--- a/drivers/net/mlx5/mlx5.h
|
|
|
a6040a |
+++ b/drivers/net/mlx5/mlx5.h
|
|
|
a6040a |
@@ -186,8 +186,6 @@ struct priv {
|
|
|
a6040a |
int mlx5_is_secondary(void);
|
|
|
a6040a |
int priv_get_ifname(const struct priv *, char (*)[IF_NAMESIZE]);
|
|
|
a6040a |
int priv_ifreq(const struct priv *, int req, struct ifreq *);
|
|
|
a6040a |
-int priv_is_ib_cntr(const char *);
|
|
|
a6040a |
-int priv_get_cntr_sysfs(struct priv *, const char *, uint64_t *);
|
|
|
a6040a |
int priv_get_num_vfs(struct priv *, uint16_t *);
|
|
|
a6040a |
int priv_get_mtu(struct priv *, uint16_t *);
|
|
|
a6040a |
int priv_set_flags(struct priv *, unsigned int, unsigned int);
|
|
|
a6040a |
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
|
|
|
a6040a |
index 5620cce..4dffa4f 100644
|
|
|
a6040a |
--- a/drivers/net/mlx5/mlx5_ethdev.c
|
|
|
a6040a |
+++ b/drivers/net/mlx5/mlx5_ethdev.c
|
|
|
a6040a |
@@ -35,6 +35,7 @@
|
|
|
a6040a |
|
|
|
a6040a |
#include <stddef.h>
|
|
|
a6040a |
#include <assert.h>
|
|
|
a6040a |
+#include <inttypes.h>
|
|
|
a6040a |
#include <unistd.h>
|
|
|
a6040a |
#include <stdint.h>
|
|
|
a6040a |
#include <stdio.h>
|
|
|
a6040a |
@@ -228,181 +229,6 @@ struct priv *
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/**
|
|
|
a6040a |
- * Check if the counter is located on ib counters file.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param[in] cntr
|
|
|
a6040a |
- * Counter name.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 1 if counter is located on ib counters file , 0 otherwise.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-int
|
|
|
a6040a |
-priv_is_ib_cntr(const char *cntr)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- if (!strcmp(cntr, "out_of_buffer"))
|
|
|
a6040a |
- return 1;
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Read from sysfs entry.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param[in] priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] entry
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param[out] buf
|
|
|
a6040a |
- * Data output buffer.
|
|
|
a6040a |
- * @param size
|
|
|
a6040a |
- * Buffer size.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 0 on success, -1 on failure and errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-priv_sysfs_read(const struct priv *priv, const char *entry,
|
|
|
a6040a |
- char *buf, size_t size)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- char ifname[IF_NAMESIZE];
|
|
|
a6040a |
- FILE *file;
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
- int err;
|
|
|
a6040a |
-
|
|
|
a6040a |
- if (priv_get_ifname(priv, &ifname))
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
-
|
|
|
a6040a |
- if (priv_is_ib_cntr(entry)) {
|
|
|
a6040a |
- MKSTR(path, "%s/ports/1/hw_counters/%s",
|
|
|
a6040a |
- priv->ibdev_path, entry);
|
|
|
a6040a |
- file = fopen(path, "rb");
|
|
|
a6040a |
- } else {
|
|
|
a6040a |
- MKSTR(path, "%s/device/net/%s/%s",
|
|
|
a6040a |
- priv->ibdev_path, ifname, entry);
|
|
|
a6040a |
- file = fopen(path, "rb");
|
|
|
a6040a |
- }
|
|
|
a6040a |
- if (file == NULL)
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- ret = fread(buf, 1, size, file);
|
|
|
a6040a |
- err = errno;
|
|
|
a6040a |
- if (((size_t)ret < size) && (ferror(file)))
|
|
|
a6040a |
- ret = -1;
|
|
|
a6040a |
- else
|
|
|
a6040a |
- ret = size;
|
|
|
a6040a |
- fclose(file);
|
|
|
a6040a |
- errno = err;
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Write to sysfs entry.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param[in] priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] entry
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param[in] buf
|
|
|
a6040a |
- * Data buffer.
|
|
|
a6040a |
- * @param size
|
|
|
a6040a |
- * Buffer size.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 0 on success, -1 on failure and errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-priv_sysfs_write(const struct priv *priv, const char *entry,
|
|
|
a6040a |
- char *buf, size_t size)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- char ifname[IF_NAMESIZE];
|
|
|
a6040a |
- FILE *file;
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
- int err;
|
|
|
a6040a |
-
|
|
|
a6040a |
- if (priv_get_ifname(priv, &ifname))
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
-
|
|
|
a6040a |
- MKSTR(path, "%s/device/net/%s/%s", priv->ibdev_path, ifname, entry);
|
|
|
a6040a |
-
|
|
|
a6040a |
- file = fopen(path, "wb");
|
|
|
a6040a |
- if (file == NULL)
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- ret = fwrite(buf, 1, size, file);
|
|
|
a6040a |
- err = errno;
|
|
|
a6040a |
- if (((size_t)ret < size) || (ferror(file)))
|
|
|
a6040a |
- ret = -1;
|
|
|
a6040a |
- else
|
|
|
a6040a |
- ret = size;
|
|
|
a6040a |
- fclose(file);
|
|
|
a6040a |
- errno = err;
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Get unsigned long sysfs property.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] name
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param[out] value
|
|
|
a6040a |
- * Value output buffer.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 0 on success, -1 on failure and errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-priv_get_sysfs_ulong(struct priv *priv, const char *name, unsigned long *value)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
- unsigned long value_ret;
|
|
|
a6040a |
- char value_str[32];
|
|
|
a6040a |
-
|
|
|
a6040a |
- ret = priv_sysfs_read(priv, name, value_str, (sizeof(value_str) - 1));
|
|
|
a6040a |
- if (ret == -1) {
|
|
|
a6040a |
- DEBUG("cannot read %s value from sysfs: %s",
|
|
|
a6040a |
- name, strerror(errno));
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- value_str[ret] = '\0';
|
|
|
a6040a |
- errno = 0;
|
|
|
a6040a |
- value_ret = strtoul(value_str, NULL, 0);
|
|
|
a6040a |
- if (errno) {
|
|
|
a6040a |
- DEBUG("invalid %s value `%s': %s", name, value_str,
|
|
|
a6040a |
- strerror(errno));
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- *value = value_ret;
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Set unsigned long sysfs property.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param[in] name
|
|
|
a6040a |
- * Entry name relative to sysfs path.
|
|
|
a6040a |
- * @param value
|
|
|
a6040a |
- * Value to set.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 0 on success, -1 on failure and errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-static int
|
|
|
a6040a |
-priv_set_sysfs_ulong(struct priv *priv, const char *name, unsigned long value)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
- MKSTR(value_str, "%lu", value);
|
|
|
a6040a |
-
|
|
|
a6040a |
- ret = priv_sysfs_write(priv, name, value_str, (sizeof(value_str) - 1));
|
|
|
a6040a |
- if (ret == -1) {
|
|
|
a6040a |
- DEBUG("cannot write %s `%s' (%lu) to sysfs: %s",
|
|
|
a6040a |
- name, value_str, value, strerror(errno));
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- }
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
* Perform ifreq ioctl() on associated Ethernet device.
|
|
|
a6040a |
*
|
|
|
a6040a |
* @param[in] priv
|
|
|
a6040a |
@@ -445,20 +271,25 @@ struct priv *
|
|
|
a6040a |
{
|
|
|
a6040a |
/* The sysfs entry name depends on the operating system. */
|
|
|
a6040a |
const char **name = (const char *[]){
|
|
|
a6040a |
- "device/sriov_numvfs",
|
|
|
a6040a |
- "device/mlx5_num_vfs",
|
|
|
a6040a |
+ "sriov_numvfs",
|
|
|
a6040a |
+ "mlx5_num_vfs",
|
|
|
a6040a |
NULL,
|
|
|
a6040a |
};
|
|
|
a6040a |
- int ret;
|
|
|
a6040a |
|
|
|
a6040a |
do {
|
|
|
a6040a |
- unsigned long ulong_num_vfs;
|
|
|
a6040a |
+ int n;
|
|
|
a6040a |
+ FILE *file;
|
|
|
a6040a |
+ MKSTR(path, "%s/device/%s", priv->ibdev_path, *name);
|
|
|
a6040a |
|
|
|
a6040a |
- ret = priv_get_sysfs_ulong(priv, *name, &ulong_num_vfs);
|
|
|
a6040a |
- if (!ret)
|
|
|
a6040a |
- *num_vfs = ulong_num_vfs;
|
|
|
a6040a |
- } while (*(++name) && ret);
|
|
|
a6040a |
- return ret;
|
|
|
a6040a |
+ file = fopen(path, "rb");
|
|
|
a6040a |
+ if (!file)
|
|
|
a6040a |
+ continue;
|
|
|
a6040a |
+ n = fscanf(file, "%" SCNu16, num_vfs);
|
|
|
a6040a |
+ fclose(file);
|
|
|
a6040a |
+ if (n == 1)
|
|
|
a6040a |
+ return 0;
|
|
|
a6040a |
+ } while (*(++name));
|
|
|
a6040a |
+ return -1;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/**
|
|
|
a6040a |
@@ -475,35 +306,12 @@ struct priv *
|
|
|
a6040a |
int
|
|
|
a6040a |
priv_get_mtu(struct priv *priv, uint16_t *mtu)
|
|
|
a6040a |
{
|
|
|
a6040a |
- unsigned long ulong_mtu;
|
|
|
a6040a |
+ struct ifreq request;
|
|
|
a6040a |
+ int ret = priv_ifreq(priv, SIOCGIFMTU, &request);
|
|
|
a6040a |
|
|
|
a6040a |
- if (priv_get_sysfs_ulong(priv, "mtu", &ulong_mtu) == -1)
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- *mtu = ulong_mtu;
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
-}
|
|
|
a6040a |
-
|
|
|
a6040a |
-/**
|
|
|
a6040a |
- * Read device counter from sysfs.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @param priv
|
|
|
a6040a |
- * Pointer to private structure.
|
|
|
a6040a |
- * @param name
|
|
|
a6040a |
- * Counter name.
|
|
|
a6040a |
- * @param[out] cntr
|
|
|
a6040a |
- * Counter output buffer.
|
|
|
a6040a |
- *
|
|
|
a6040a |
- * @return
|
|
|
a6040a |
- * 0 on success, -1 on failure and errno is set.
|
|
|
a6040a |
- */
|
|
|
a6040a |
-int
|
|
|
a6040a |
-priv_get_cntr_sysfs(struct priv *priv, const char *name, uint64_t *cntr)
|
|
|
a6040a |
-{
|
|
|
a6040a |
- unsigned long ulong_ctr;
|
|
|
a6040a |
-
|
|
|
a6040a |
- if (priv_get_sysfs_ulong(priv, name, &ulong_ctr) == -1)
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- *cntr = ulong_ctr;
|
|
|
a6040a |
+ if (ret)
|
|
|
a6040a |
+ return ret;
|
|
|
a6040a |
+ *mtu = request.ifr_mtu;
|
|
|
a6040a |
return 0;
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
@@ -521,15 +329,9 @@ struct priv *
|
|
|
a6040a |
static int
|
|
|
a6040a |
priv_set_mtu(struct priv *priv, uint16_t mtu)
|
|
|
a6040a |
{
|
|
|
a6040a |
- uint16_t new_mtu;
|
|
|
a6040a |
+ struct ifreq request = { .ifr_mtu = mtu, };
|
|
|
a6040a |
|
|
|
a6040a |
- if (priv_set_sysfs_ulong(priv, "mtu", mtu) ||
|
|
|
a6040a |
- priv_get_mtu(priv, &new_mtu))
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- if (new_mtu == mtu)
|
|
|
a6040a |
- return 0;
|
|
|
a6040a |
- errno = EINVAL;
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
+ return priv_ifreq(priv, SIOCSIFMTU, &request);
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/**
|
|
|
a6040a |
@@ -548,13 +350,14 @@ struct priv *
|
|
|
a6040a |
int
|
|
|
a6040a |
priv_set_flags(struct priv *priv, unsigned int keep, unsigned int flags)
|
|
|
a6040a |
{
|
|
|
a6040a |
- unsigned long tmp;
|
|
|
a6040a |
+ struct ifreq request;
|
|
|
a6040a |
+ int ret = priv_ifreq(priv, SIOCGIFFLAGS, &request);
|
|
|
a6040a |
|
|
|
a6040a |
- if (priv_get_sysfs_ulong(priv, "flags", &tmp) == -1)
|
|
|
a6040a |
- return -1;
|
|
|
a6040a |
- tmp &= keep;
|
|
|
a6040a |
- tmp |= (flags & (~keep));
|
|
|
a6040a |
- return priv_set_sysfs_ulong(priv, "flags", tmp);
|
|
|
a6040a |
+ if (ret)
|
|
|
a6040a |
+ return ret;
|
|
|
a6040a |
+ request.ifr_flags &= keep;
|
|
|
a6040a |
+ request.ifr_flags |= flags & ~keep;
|
|
|
a6040a |
+ return priv_ifreq(priv, SIOCSIFFLAGS, &request);
|
|
|
a6040a |
}
|
|
|
a6040a |
|
|
|
a6040a |
/**
|
|
|
a6040a |
diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c
|
|
|
a6040a |
index 5e225d3..48422cc 100644
|
|
|
a6040a |
--- a/drivers/net/mlx5/mlx5_stats.c
|
|
|
a6040a |
+++ b/drivers/net/mlx5/mlx5_stats.c
|
|
|
a6040a |
@@ -31,8 +31,11 @@
|
|
|
a6040a |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
a6040a |
*/
|
|
|
a6040a |
|
|
|
a6040a |
+#include <inttypes.h>
|
|
|
a6040a |
#include <linux/sockios.h>
|
|
|
a6040a |
#include <linux/ethtool.h>
|
|
|
a6040a |
+#include <stdint.h>
|
|
|
a6040a |
+#include <stdio.h>
|
|
|
a6040a |
|
|
|
a6040a |
#include <rte_ethdev.h>
|
|
|
a6040a |
#include <rte_common.h>
|
|
|
a6040a |
@@ -47,6 +50,7 @@ struct mlx5_counter_ctrl {
|
|
|
a6040a |
char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE];
|
|
|
a6040a |
/* Name of the counter on the device table. */
|
|
|
a6040a |
char ctr_name[RTE_ETH_XSTATS_NAME_SIZE];
|
|
|
a6040a |
+ uint32_t ib:1; /**< Nonzero for IB counters. */
|
|
|
a6040a |
};
|
|
|
a6040a |
|
|
|
a6040a |
static const struct mlx5_counter_ctrl mlx5_counters_init[] = {
|
|
|
a6040a |
@@ -121,6 +125,7 @@ struct mlx5_counter_ctrl {
|
|
|
a6040a |
{
|
|
|
a6040a |
.dpdk_name = "rx_out_of_buffer",
|
|
|
a6040a |
.ctr_name = "out_of_buffer",
|
|
|
a6040a |
+ .ib = 1,
|
|
|
a6040a |
},
|
|
|
a6040a |
};
|
|
|
a6040a |
|
|
|
a6040a |
@@ -157,13 +162,24 @@ struct mlx5_counter_ctrl {
|
|
|
a6040a |
return -1;
|
|
|
a6040a |
}
|
|
|
a6040a |
for (i = 0; i != xstats_n; ++i) {
|
|
|
a6040a |
- if (priv_is_ib_cntr(mlx5_counters_init[i].ctr_name))
|
|
|
a6040a |
- priv_get_cntr_sysfs(priv,
|
|
|
a6040a |
- mlx5_counters_init[i].ctr_name,
|
|
|
a6040a |
- &stats[i]);
|
|
|
a6040a |
- else
|
|
|
a6040a |
+ if (mlx5_counters_init[i].ib) {
|
|
|
a6040a |
+ FILE *file;
|
|
|
a6040a |
+ MKSTR(path, "%s/ports/1/hw_counters/%s",
|
|
|
a6040a |
+ priv->ibdev_path,
|
|
|
a6040a |
+ mlx5_counters_init[i].ctr_name);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ file = fopen(path, "rb");
|
|
|
a6040a |
+ if (file) {
|
|
|
a6040a |
+ int n = fscanf(file, "%" SCNu64, &stats[i]);
|
|
|
a6040a |
+
|
|
|
a6040a |
+ fclose(file);
|
|
|
a6040a |
+ if (n != 1)
|
|
|
a6040a |
+ stats[i] = 0;
|
|
|
a6040a |
+ }
|
|
|
a6040a |
+ } else {
|
|
|
a6040a |
stats[i] = (uint64_t)
|
|
|
a6040a |
et_stats->data[xstats_ctrl->dev_table_idx[i]];
|
|
|
a6040a |
+ }
|
|
|
a6040a |
}
|
|
|
a6040a |
return 0;
|
|
|
a6040a |
}
|
|
|
a6040a |
@@ -246,7 +262,7 @@ struct mlx5_counter_ctrl {
|
|
|
a6040a |
}
|
|
|
a6040a |
}
|
|
|
a6040a |
for (j = 0; j != xstats_n; ++j) {
|
|
|
a6040a |
- if (priv_is_ib_cntr(mlx5_counters_init[j].ctr_name))
|
|
|
a6040a |
+ if (mlx5_counters_init[j].ib)
|
|
|
a6040a |
continue;
|
|
|
a6040a |
if (xstats_ctrl->dev_table_idx[j] >= dev_stats_n) {
|
|
|
a6040a |
WARN("counter \"%s\" is not recognized",
|
|
|
a6040a |
--
|
|
|
a6040a |
1.8.3.1
|
|
|
a6040a |
|