* [PATCH v4 2/8] net: phy: Fix the register offsets in Broadcom iProc mdio mux driver
From: Arun Parameswaran @ 2018-08-02 0:53 UTC (permalink / raw)
To: David S. Miller, Florian Fainelli, Andrew Lunn, Rob Herring,
Mark Rutland, Ray Jui, Scott Branden, Catalin Marinas,
Will Deacon
Cc: netdev, devicetree, linux-arm-kernel, linux-kernel,
bcm-kernel-feedback-list, Arun Parameswaran
In-Reply-To: <1533171233-14557-1-git-send-email-arun.parameswaran@broadcom.com>
Modify the register offsets in the Broadcom iProc mdio mux to start
from the top of the register address space.
Earlier, the base address pointed to the end of the block's register
space. The base address will now point to the start of the mdio's
address space. The offsets have been fixed to match this.
Signed-off-by: Arun Parameswaran <arun.parameswaran@broadcom.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/mdio-mux-bcm-iproc.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/mdio-mux-bcm-iproc.c b/drivers/net/phy/mdio-mux-bcm-iproc.c
index 0831b71..48bb74a 100644
--- a/drivers/net/phy/mdio-mux-bcm-iproc.c
+++ b/drivers/net/phy/mdio-mux-bcm-iproc.c
@@ -22,7 +22,7 @@
#include <linux/mdio-mux.h>
#include <linux/delay.h>
-#define MDIO_PARAM_OFFSET 0x00
+#define MDIO_PARAM_OFFSET 0x23c
#define MDIO_PARAM_MIIM_CYCLE 29
#define MDIO_PARAM_INTERNAL_SEL 25
#define MDIO_PARAM_BUS_ID 22
@@ -30,20 +30,22 @@
#define MDIO_PARAM_PHY_ID 16
#define MDIO_PARAM_PHY_DATA 0
-#define MDIO_READ_OFFSET 0x04
+#define MDIO_READ_OFFSET 0x240
#define MDIO_READ_DATA_MASK 0xffff
-#define MDIO_ADDR_OFFSET 0x08
+#define MDIO_ADDR_OFFSET 0x244
-#define MDIO_CTRL_OFFSET 0x0C
+#define MDIO_CTRL_OFFSET 0x248
#define MDIO_CTRL_WRITE_OP 0x1
#define MDIO_CTRL_READ_OP 0x2
-#define MDIO_STAT_OFFSET 0x10
+#define MDIO_STAT_OFFSET 0x24c
#define MDIO_STAT_DONE 1
#define BUS_MAX_ADDR 32
#define EXT_BUS_START_ADDR 16
+#define MDIO_REG_ADDR_SPACE_SIZE 0x250
+
struct iproc_mdiomux_desc {
void *mux_handle;
void __iomem *base;
@@ -169,6 +171,14 @@ static int mdio_mux_iproc_probe(struct platform_device *pdev)
md->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res->start & 0xfff) {
+ /* For backward compatibility in case the
+ * base address is specified with an offset.
+ */
+ dev_info(&pdev->dev, "fix base address in dt-blob\n");
+ res->start &= ~0xfff;
+ res->end = res->start + MDIO_REG_ADDR_SPACE_SIZE - 1;
+ }
md->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(md->base)) {
dev_err(&pdev->dev, "failed to ioremap register\n");
--
1.9.1
^ permalink raw reply related
* [PATCH v4 1/8] dt-bindings: net: Fix Broadcom iProc mdio mux driver base address
From: Arun Parameswaran @ 2018-08-02 0:53 UTC (permalink / raw)
To: David S. Miller, Florian Fainelli, Andrew Lunn, Rob Herring,
Mark Rutland, Ray Jui, Scott Branden, Catalin Marinas,
Will Deacon
Cc: netdev, devicetree, linux-arm-kernel, linux-kernel,
bcm-kernel-feedback-list, Arun Parameswaran
In-Reply-To: <1533171233-14557-1-git-send-email-arun.parameswaran@broadcom.com>
Modify the base address of the Broadcom iProc MDIO mux driver to
point to the start of the block's register address space.
Signed-off-by: Arun Parameswaran <arun.parameswaran@broadcom.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt b/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt
index dfe287a..dc8aa68 100644
--- a/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt
+++ b/Documentation/devicetree/bindings/net/brcm,mdio-mux-iproc.txt
@@ -18,9 +18,9 @@ at- Documentation/devicetree/bindings/net/mdio-mux.txt
for example:
- mdio_mux_iproc: mdio-mux@6602023c {
+ mdio_mux_iproc: mdio-mux@66020000 {
compatible = "brcm,mdio-mux-iproc";
- reg = <0x6602023c 0x14>;
+ reg = <0x66020000 0x250>;
#address-cells = <1>;
#size-cells = <0>;
--
1.9.1
^ permalink raw reply related
* [PATCH v4 0/8] Add clock config and pm support to bcm iProc mdio mux
From: Arun Parameswaran @ 2018-08-02 0:53 UTC (permalink / raw)
To: David S. Miller, Florian Fainelli, Andrew Lunn, Rob Herring,
Mark Rutland, Ray Jui, Scott Branden, Catalin Marinas,
Will Deacon
Cc: netdev, devicetree, linux-arm-kernel, linux-kernel,
bcm-kernel-feedback-list, Arun Parameswaran
Hi,
The patchset is based on David Miller's "net-next" repo.
The patchset extends the Broadcom iProc mdio mux to add support for
suspend/resume and the ability to configure the internal clock
divider. The patchset also sets the scan control register to
disable external master access.
The base address of the mdio-mux-bcm-iproc is modified to point to the
start of the mdio block's address space, to be able to access all the
mdio's registers. The missing registers are required to configure the
internal clock divider registers in some of the Broadcom SoC's.
Changes from v3:
- Removed 'platform_set_drvdata(pdev, NULL)' call (in patch 5/8)
- Fixed the return code handling for the devm_clk_get() call (in patch
7/8)
- Added Reviewed-by tag to Patch 8/8
Changes from v2:
- Addressed Andrew's comments:
- Moved to using devm_mdiobus_alloc. Added this as a separate patch.
- Changed to reverse christmas tree order for variable declaration in
the clock patch
- Addressed Florian's comments:
- Removed null checks for the clock before calling unprepare in
both clock and pm patches.
- Added check for EPROBE_DEFER when fetching the clock in the clock
patch.
- The patch to use the devm API has been added before the clock & pm
patches. This patch is now patch '5' in the series.
- Added reviewed-by tags to commit messages of patches which remain
unmodified from v2.
- Modified PM patch to use platform_get_drvdata() in suspend/resume
API's, similar to the recent fix that went in for the remove()
api.
Changes from v1:
- Addressed Andrew's comments.
- Reworked the patches to be based on 'net-next'
- Removed 'fixes' from the commit messages, the changes are related
to the new features being added.
- Maintained backward compatibility to older dt-blob's specifying
base addresse with an offset. The correction is applied in the
driver and a message is printed to update the dt-blob.
- Re-worked and re-ordered the last four patches (4-7).
- Added setting of the scan control register as a new patch
- Added a call to 'clk_prepare_enable()' in the patch that adds
the clock config support, removed the debug message when clock
is not passed.
- Simplified the pm support patch (removed the array used for the
save/restore logic).
Thanks
Arun Parameswaran (8):
dt-bindings: net: Fix Broadcom iProc mdio mux driver base address
net: phy: Fix the register offsets in Broadcom iProc mdio mux driver
arm64: dts: Fix the base address of the Broadcom iProc mdio mux
net: phy: Disable external master access in bcm mdio mux driver
net: phy: Use devm api for mdio bus allocation in bcm iproc mdio mux
dt-bindings: net: Add clock handle to Broadcom iProc mdio mux
net: phy: Add support to configure clock in Broadcom iProc mdio mux
net: phy: Add pm support to Broadcom iProc mdio mux driver
.../bindings/net/brcm,mdio-mux-iproc.txt | 7 +-
arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi | 4 +-
.../arm64/boot/dts/broadcom/stingray/stingray.dtsi | 4 +-
drivers/net/phy/mdio-mux-bcm-iproc.c | 108 ++++++++++++++++++---
4 files changed, 106 insertions(+), 17 deletions(-)
--
1.9.1
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: force_napi_tx module param.
From: Michael S. Tsirkin @ 2018-08-01 22:48 UTC (permalink / raw)
To: Willem de Bruijn
Cc: David Miller, caleb.raitto, Jason Wang, Network Development,
Caleb Raitto
In-Reply-To: <CAF=yD-+Wvy_93h2=OV=hkrj7SRoR_NMpOyc8qMStUy74+6-t+Q@mail.gmail.com>
On Wed, Aug 01, 2018 at 06:43:53PM -0400, Willem de Bruijn wrote:
> > > So e.g. we could set an affinity hint to a group of CPUs that
> > > > might transmit to this queue.
> > >
> > > We also want to set the xps mask for all cpus in the group to this queue.
> > >
> > > Is there a benefit over explicitly choosing one cpu from the set, btw?
> >
> > If only one CPU actually transmits on this queue then probably yes.
> > And virtio doesn't know whether that's the case.
>
> Oh, yes, good example.
>
> To plumb that through, vp_set_vq_affinity would have to take a cpu
> mask like irq_set_affinity_hint, instead of a single value.
>
> Though I don't suggest doing that as part of the core
> virtnet_set_affinity changes.
Why not? It seems a reasonable thing to do.
--
MST
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: force_napi_tx module param.
From: Willem de Bruijn @ 2018-08-01 22:43 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: David Miller, caleb.raitto, Jason Wang, Network Development,
Caleb Raitto
In-Reply-To: <20180802012405-mutt-send-email-mst@kernel.org>
> > So e.g. we could set an affinity hint to a group of CPUs that
> > > might transmit to this queue.
> >
> > We also want to set the xps mask for all cpus in the group to this queue.
> >
> > Is there a benefit over explicitly choosing one cpu from the set, btw?
>
> If only one CPU actually transmits on this queue then probably yes.
> And virtio doesn't know whether that's the case.
Oh, yes, good example.
To plumb that through, vp_set_vq_affinity would have to take a cpu
mask like irq_set_affinity_hint, instead of a single value.
Though I don't suggest doing that as part of the core
virtnet_set_affinity changes.
^ permalink raw reply
* [PATCH net-next] xen-netback: use true and false for boolean values
From: Gustavo A. R. Silva @ 2018-08-02 0:31 UTC (permalink / raw)
To: Wei Liu, Paul Durrant, David S. Miller
Cc: xen-devel, netdev, linux-kernel, Gustavo A. R. Silva
Return statements in functions returning bool should use true or false
instead of an integer value.
This issue was detected with the help of Coccinelle.
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
---
drivers/net/xen-netback/netback.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index a27daa2..3621e05 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1603,9 +1603,9 @@ static void xenvif_ctrl_action(struct xenvif *vif)
static bool xenvif_ctrl_work_todo(struct xenvif *vif)
{
if (likely(RING_HAS_UNCONSUMED_REQUESTS(&vif->ctrl)))
- return 1;
+ return true;
- return 0;
+ return false;
}
irqreturn_t xenvif_ctrl_irq_fn(int irq, void *data)
--
2.7.4
^ permalink raw reply related
* [PATCH v6 bpf-next 11/14] bpf/test_run: support cgroup local storage
From: Roman Gushchin @ 2018-08-01 22:37 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
In-Reply-To: <20180801223740.11252-1-guro@fb.com>
Allocate a temporary cgroup storage to use for bpf program test runs.
Because the test program is not actually attached to a cgroup,
the storage is allocated manually just for the execution
of the bpf program.
If the program is executed multiple times, the storage is not zeroed
on each run, emulating multiple runs of the program, attached to
a real cgroup.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
net/bpf/test_run.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 22a78eedf4b1..f4078830ea50 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -11,12 +11,14 @@
#include <linux/filter.h>
#include <linux/sched/signal.h>
-static __always_inline u32 bpf_test_run_one(struct bpf_prog *prog, void *ctx)
+static __always_inline u32 bpf_test_run_one(struct bpf_prog *prog, void *ctx,
+ struct bpf_cgroup_storage *storage)
{
u32 ret;
preempt_disable();
rcu_read_lock();
+ bpf_cgroup_storage_set(storage);
ret = BPF_PROG_RUN(prog, ctx);
rcu_read_unlock();
preempt_enable();
@@ -26,14 +28,19 @@ static __always_inline u32 bpf_test_run_one(struct bpf_prog *prog, void *ctx)
static u32 bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 *time)
{
+ struct bpf_cgroup_storage *storage = NULL;
u64 time_start, time_spent = 0;
u32 ret = 0, i;
+ storage = bpf_cgroup_storage_alloc(prog);
+ if (IS_ERR(storage))
+ return PTR_ERR(storage);
+
if (!repeat)
repeat = 1;
time_start = ktime_get_ns();
for (i = 0; i < repeat; i++) {
- ret = bpf_test_run_one(prog, ctx);
+ ret = bpf_test_run_one(prog, ctx, storage);
if (need_resched()) {
if (signal_pending(current))
break;
@@ -46,6 +53,8 @@ static u32 bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 *time)
do_div(time_spent, repeat);
*time = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
+ bpf_cgroup_storage_free(storage);
+
return ret;
}
--
2.14.4
^ permalink raw reply related
* [PATCH v6 bpf-next 03/14] bpf: pass a pointer to a cgroup storage using pcpu variable
From: Roman Gushchin @ 2018-08-01 22:37 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
In-Reply-To: <20180801223740.11252-1-guro@fb.com>
This commit introduces the bpf_cgroup_storage_set() helper,
which will be used to pass a pointer to a cgroup storage
to the bpf helper.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
include/linux/bpf-cgroup.h | 15 +++++++++++++++
kernel/bpf/local_storage.c | 2 ++
2 files changed, 17 insertions(+)
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 7d00d58869ed..9a144ddbbc8f 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -4,6 +4,7 @@
#include <linux/errno.h>
#include <linux/jump_label.h>
+#include <linux/percpu.h>
#include <linux/rbtree.h>
#include <uapi/linux/bpf.h>
@@ -21,6 +22,8 @@ struct bpf_cgroup_storage;
extern struct static_key_false cgroup_bpf_enabled_key;
#define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key)
+DECLARE_PER_CPU(void*, bpf_cgroup_storage);
+
struct bpf_cgroup_storage_map;
struct bpf_storage_buffer {
@@ -97,6 +100,17 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
short access, enum bpf_attach_type type);
+static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage *storage)
+{
+ struct bpf_storage_buffer *buf;
+
+ if (!storage)
+ return;
+
+ buf = READ_ONCE(storage->buf);
+ this_cpu_write(bpf_cgroup_storage, &buf->data[0]);
+}
+
struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog);
void bpf_cgroup_storage_free(struct bpf_cgroup_storage *storage);
void bpf_cgroup_storage_link(struct bpf_cgroup_storage *storage,
@@ -250,6 +264,7 @@ static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,
return -EINVAL;
}
+static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage *storage) {}
static inline int bpf_cgroup_storage_assign(struct bpf_prog *prog,
struct bpf_map *map) { return 0; }
static inline void bpf_cgroup_storage_release(struct bpf_prog *prog,
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index fd5edabc48b3..cd0b115c2395 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -7,6 +7,8 @@
#include <linux/rbtree.h>
#include <linux/slab.h>
+DEFINE_PER_CPU(void*, bpf_cgroup_storage);
+
#ifdef CONFIG_CGROUP_BPF
#define LOCAL_STORAGE_CREATE_FLAG_MASK \
--
2.14.4
^ permalink raw reply related
* [PATCH v6 bpf-next 08/14] bpf: introduce the bpf_get_local_storage() helper function
From: Roman Gushchin @ 2018-08-01 22:37 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
In-Reply-To: <20180801223740.11252-1-guro@fb.com>
The bpf_get_local_storage() helper function is used
to get a pointer to the bpf local storage from a bpf program.
It takes a pointer to a storage map and flags as arguments.
Right now it accepts only cgroup storage maps, and flags
argument has to be 0. Further it can be extended to support
other types of local storage: e.g. thread local storage etc.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---
include/linux/bpf.h | 2 ++
include/uapi/linux/bpf.h | 21 ++++++++++++++++++++-
kernel/bpf/cgroup.c | 2 ++
kernel/bpf/core.c | 1 +
kernel/bpf/helpers.c | 20 ++++++++++++++++++++
kernel/bpf/verifier.c | 18 ++++++++++++++++++
net/core/filter.c | 23 ++++++++++++++++++++++-
7 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index ca4ac2a39def..cd8790d2c6ed 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -788,6 +788,8 @@ extern const struct bpf_func_proto bpf_sock_map_update_proto;
extern const struct bpf_func_proto bpf_sock_hash_update_proto;
extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto;
+extern const struct bpf_func_proto bpf_get_local_storage_proto;
+
/* Shared helpers among cBPF and eBPF. */
void bpf_user_rnd_init_once(void);
u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index b10118ee5afe..dd5758dc35d3 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2095,6 +2095,24 @@ union bpf_attr {
* Return
* A 64-bit integer containing the current cgroup id based
* on the cgroup within which the current task is running.
+ *
+ * void* get_local_storage(void *map, u64 flags)
+ * Description
+ * Get the pointer to the local storage area.
+ * The type and the size of the local storage is defined
+ * by the *map* argument.
+ * The *flags* meaning is specific for each map type,
+ * and has to be 0 for cgroup local storage.
+ *
+ * Depending on the bpf program type, a local storage area
+ * can be shared between multiple instances of the bpf program,
+ * running simultaneously.
+ *
+ * A user should care about the synchronization by himself.
+ * For example, by using the BPF_STX_XADD instruction to alter
+ * the shared data.
+ * Return
+ * Pointer to the local storage area.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2177,7 +2195,8 @@ union bpf_attr {
FN(rc_repeat), \
FN(rc_keydown), \
FN(skb_cgroup_id), \
- FN(get_current_cgroup_id),
+ FN(get_current_cgroup_id), \
+ FN(get_local_storage),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index ddfa6cc13e57..0a4fe5a7dc91 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -684,6 +684,8 @@ cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_map_delete_elem_proto;
case BPF_FUNC_get_current_uid_gid:
return &bpf_get_current_uid_gid_proto;
+ case BPF_FUNC_get_local_storage:
+ return &bpf_get_local_storage_proto;
case BPF_FUNC_trace_printk:
if (capable(CAP_SYS_ADMIN))
return bpf_get_trace_printk_proto();
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 9abcf25ebf9f..4d09e610777f 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1795,6 +1795,7 @@ const struct bpf_func_proto bpf_get_current_comm_proto __weak;
const struct bpf_func_proto bpf_sock_map_update_proto __weak;
const struct bpf_func_proto bpf_sock_hash_update_proto __weak;
const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
+const struct bpf_func_proto bpf_get_local_storage_proto __weak;
const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
{
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 73065e2d23c2..1991466b8327 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -193,4 +193,24 @@ const struct bpf_func_proto bpf_get_current_cgroup_id_proto = {
.gpl_only = false,
.ret_type = RET_INTEGER,
};
+
+DECLARE_PER_CPU(void*, bpf_cgroup_storage);
+
+BPF_CALL_2(bpf_get_local_storage, struct bpf_map *, map, u64, flags)
+{
+ /* map and flags arguments are not used now,
+ * but provide an ability to extend the API
+ * for other types of local storages.
+ * verifier checks that their values are correct.
+ */
+ return (unsigned long) this_cpu_read(bpf_cgroup_storage);
+}
+
+const struct bpf_func_proto bpf_get_local_storage_proto = {
+ .func = bpf_get_local_storage,
+ .gpl_only = false,
+ .ret_type = RET_PTR_TO_MAP_VALUE,
+ .arg1_type = ARG_CONST_MAP_PTR,
+ .arg2_type = ARG_ANYTHING,
+};
#endif
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1ede16c8bb40..587468a9c37d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2127,6 +2127,10 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
func_id != BPF_FUNC_current_task_under_cgroup)
goto error;
break;
+ case BPF_MAP_TYPE_CGROUP_STORAGE:
+ if (func_id != BPF_FUNC_get_local_storage)
+ goto error;
+ break;
/* devmap returns a pointer to a live net_device ifindex that we cannot
* allow to be modified from bpf side. So do not allow lookup elements
* for now.
@@ -2209,6 +2213,10 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
if (map->map_type != BPF_MAP_TYPE_SOCKHASH)
goto error;
break;
+ case BPF_FUNC_get_local_storage:
+ if (map->map_type != BPF_MAP_TYPE_CGROUP_STORAGE)
+ goto error;
+ break;
default:
break;
}
@@ -2533,6 +2541,16 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
}
regs = cur_regs(env);
+
+ /* check that flags argument in get_local_storage(map, flags) is 0,
+ * this is required because get_local_storage() can't return an error.
+ */
+ if (func_id == BPF_FUNC_get_local_storage &&
+ !register_is_null(®s[BPF_REG_2])) {
+ verbose(env, "get_local_storage() doesn't support non-zero flags\n");
+ return -EINVAL;
+ }
+
/* reset caller saved regs */
for (i = 0; i < CALLER_SAVED_REGS; i++) {
mark_reg_not_init(env, regs, caller_saved[i]);
diff --git a/net/core/filter.c b/net/core/filter.c
index 9bb9a4488e25..9f73aae2f089 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4820,6 +4820,8 @@ sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
*/
case BPF_FUNC_get_current_uid_gid:
return &bpf_get_current_uid_gid_proto;
+ case BPF_FUNC_get_local_storage:
+ return &bpf_get_local_storage_proto;
default:
return bpf_base_func_proto(func_id);
}
@@ -4844,6 +4846,8 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
}
case BPF_FUNC_get_socket_cookie:
return &bpf_get_socket_cookie_sock_addr_proto;
+ case BPF_FUNC_get_local_storage:
+ return &bpf_get_local_storage_proto;
default:
return bpf_base_func_proto(func_id);
}
@@ -4866,6 +4870,17 @@ sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
}
}
+static const struct bpf_func_proto *
+cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
+{
+ switch (func_id) {
+ case BPF_FUNC_get_local_storage:
+ return &bpf_get_local_storage_proto;
+ default:
+ return sk_filter_func_proto(func_id, prog);
+ }
+}
+
static const struct bpf_func_proto *
tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
@@ -4988,6 +5003,8 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_sock_hash_update_proto;
case BPF_FUNC_get_socket_cookie:
return &bpf_get_socket_cookie_sock_ops_proto;
+ case BPF_FUNC_get_local_storage:
+ return &bpf_get_local_storage_proto;
default:
return bpf_base_func_proto(func_id);
}
@@ -5007,6 +5024,8 @@ sk_msg_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_msg_cork_bytes_proto;
case BPF_FUNC_msg_pull_data:
return &bpf_msg_pull_data_proto;
+ case BPF_FUNC_get_local_storage:
+ return &bpf_get_local_storage_proto;
default:
return bpf_base_func_proto(func_id);
}
@@ -5034,6 +5053,8 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_sk_redirect_map_proto;
case BPF_FUNC_sk_redirect_hash:
return &bpf_sk_redirect_hash_proto;
+ case BPF_FUNC_get_local_storage:
+ return &bpf_get_local_storage_proto;
default:
return bpf_base_func_proto(func_id);
}
@@ -6838,7 +6859,7 @@ const struct bpf_prog_ops xdp_prog_ops = {
};
const struct bpf_verifier_ops cg_skb_verifier_ops = {
- .get_func_proto = sk_filter_func_proto,
+ .get_func_proto = cg_skb_func_proto,
.is_valid_access = sk_filter_is_valid_access,
.convert_ctx_access = bpf_convert_ctx_access,
};
--
2.14.4
^ permalink raw reply related
* Re: [pull request][net-next 00/10] Mellanox, mlx5 and devlink updates 2018-07-31
From: Alexander Duyck @ 2018-08-01 22:34 UTC (permalink / raw)
To: Saeed Mahameed
Cc: David S. Miller, Netdev, Jiri Pirko, Jakub Kicinski,
Bjorn Helgaas
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
On Wed, Aug 1, 2018 at 2:52 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> Hi Dave,
>
> This series provides devlink parameters updates to both devlink API and
> mlx5 driver, it is a 2nd iteration of the dropped patches sent in a previous
> mlx5 submission "net/mlx5: Support PCIe buffer congestion handling via
> Devlink" to address review comments [1].
>
> Changes from the original series:
> - According to the discussion outcome, we are keeping the congestion control
> setting as mlx5 device specific for the current HW generation.
> - Changed the congestion_mode and congestion action param type to string
> - Added patches to fix devlink handling of param type string
> - Added a patch which adds extack messages support for param set.
> - At the end of this series, I've added yet another mlx5 devlink related
> feature, firmware snapshot support.
>
> For more information please see tag log below.
>
> Please pull and let me know if there's any problem.
>
> [1] https://patchwork.ozlabs.org/patch/945996/
>
> Thanks,
> Saeed.
>
> ---
>
> The following changes since commit e6476c21447c4b17c47e476aade6facf050f31e8:
>
> net: remove bogus RCU annotations on socket.wq (2018-07-31 12:40:22 -0700)
>
> are available in the Git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git tags/mlx5-updates-2018-08-01
>
> for you to fetch changes up to 2ac6108c65ffcb1e5eab1fba1fd59272604d1c32:
>
> net/mlx5: Use devlink region_snapshot parameter (2018-08-01 14:49:09 -0700)
>
> ----------------------------------------------------------------
> mlx5-updates-2018-08-01
>
> This series provides devlink parameters updates to both devlink API and
> mlx5 driver,
>
> 1) Devlink changes: (Moshe Shemesh)
> The first two patches fix devlink param infrastructure for string type
> params.
> The third patch adds a devlink helper function to safely copy string from
> driver to devlink.
> The forth patch adds extack support for param set.
>
> 2) mlx5 specific congestion parameters: (Eran Ben Elisha)
> Next three patches add new devlink driver specific params for controlling
> congestion action and mode, using string type params and extack messages support.
>
> This congestion mode enables hw workaround in specific devices which is
> controlled by devlink driver-specific params. The workaround is device
> specific for this NIC generation, the next NIC will not need it.
>
> Congestion parameters:
> - Congestion action
> HW W/A mechanism in the PCIe buffer which monitors the amount of
> consumed PCIe buffer per host. This mechanism supports the
> following actions in case of threshold overflow:
> - Disabled - NOP (Default)
> - Drop
> - Mark - Mark CE bit in the CQE of received packet
> - Congestion mode
> - Aggressive - Aggressive static trigger threshold (Default)
> - Dynamic - Dynamically change the trigger threshold
>
> 3) mlx5 firmware snapshot support via devlink: (Alex Vesker)
> Last three patches, add the support for capturing region snapshot of the
> firmware crspace during critical errors, using devlink region_snapshot
> parameter.
>
> -Saeed.
>
> ----------------------------------------------------------------
> Alex Vesker (3):
> net/mlx5: Add Vendor Specific Capability access gateway
> net/mlx5: Add Crdump FW snapshot support
> net/mlx5: Use devlink region_snapshot parameter
>
> Eran Ben Elisha (3):
> net/mlx5: Move all devlink related functions calls to devlink.c
> net/mlx5: Add MPEGC register configuration functionality
> net/mlx5: Enable PCIe buffer congestion handling workaround via devlink
>
> Moshe Shemesh (4):
> devlink: Fix param set handling for string type
> devlink: Fix param cmode driverinit for string type
> devlink: Add helper function for safely copy string param
> devlink: Add extack messages support to param set
>
> drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 3 +-
> drivers/net/ethernet/mellanox/mlx4/main.c | 6 +-
> drivers/net/ethernet/mellanox/mlx5/core/Makefile | 3 +-
> drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 388 +++++++++++++++++++++
> drivers/net/ethernet/mellanox/mlx5/core/devlink.h | 13 +
> .../net/ethernet/mellanox/mlx5/core/diag/crdump.c | 223 ++++++++++++
> drivers/net/ethernet/mellanox/mlx5/core/health.c | 3 +
> drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h | 4 +
> .../net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c | 320 +++++++++++++++++
> .../net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h | 56 +++
> drivers/net/ethernet/mellanox/mlx5/core/main.c | 10 +-
> include/linux/mlx5/driver.h | 5 +
> include/net/devlink.h | 15 +-
> net/core/devlink.c | 44 ++-
> 14 files changed, 1076 insertions(+), 17 deletions(-)
> create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/devlink.c
> create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/devlink.h
> create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
> create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
> create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h
So after looking over the patch set the one thing I would ask for in
this is some sort of documentation at a minimum. As a user I don't see
how you can expect someone to be able to use this when the naming of
things are pretty cryptic and there is no real explanation anywhere if
you don't go through and read the patch description itself. When you
start adding driver specific interfaces, you should at least start
adding vendor specific documentation.
Also I don't see how using a vendor specific configuration space
section can be done without adding some tie-ins to the PCI core files
because it should be possible to race with someone poking at the
register space via something like setpci/lspci. Also one of the things
that came up was that drivers are not supposed to be banging on the
PCI configuration space at will, and it seems like this patch set is
doing exactly that through the VSC block.
- Alex
^ permalink raw reply
* Re: [net-next 01/10] devlink: Fix param set handling for string type
From: Jakub Kicinski @ 2018-08-01 22:33 UTC (permalink / raw)
To: Saeed Mahameed, Jiri Pirko
Cc: David S. Miller, netdev, Alexander Duyck, Bjorn Helgaas,
Moshe Shemesh
In-Reply-To: <20180801215255.6642-2-saeedm@mellanox.com>
On Wed, 1 Aug 2018 14:52:46 -0700, Saeed Mahameed wrote:
> From: Moshe Shemesh <moshe@mellanox.com>
>
> In case devlink param type is string, it needs to copy the string value
> it got from the input to devlink_param_value.
>
> Fixes: e3b7ca18ad7b ("devlink: Add param set command")
> Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
> ---
> include/net/devlink.h | 2 +-
> net/core/devlink.c | 3 ++-
> 2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/devlink.h b/include/net/devlink.h
> index b9b89d6604d4..b0e17c025fdc 100644
> --- a/include/net/devlink.h
> +++ b/include/net/devlink.h
> @@ -311,7 +311,7 @@ union devlink_param_value {
> u8 vu8;
> u16 vu16;
> u32 vu32;
> - const char *vstr;
> + char vstr[DEVLINK_PARAM_MAX_STRING_VALUE];
> bool vbool;
> };
>
> diff --git a/net/core/devlink.c b/net/core/devlink.c
> index 65fc366a78a4..61e126c28526 100644
> --- a/net/core/devlink.c
> +++ b/net/core/devlink.c
> @@ -3014,7 +3014,8 @@ devlink_param_value_get_from_info(const struct devlink_param *param,
> if (nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) >
> DEVLINK_PARAM_MAX_STRING_VALUE)
> return -EINVAL;
> - value->vstr = nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
> + strcpy(value->vstr,
> + nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
DEVLINK_ATTR_PARAM_VALUE_DATA is a type mux, I'm struggling to find in
the code where it's checked for being null-terminated for strings.
> break;
> case DEVLINK_PARAM_TYPE_BOOL:
> value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ?
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: force_napi_tx module param.
From: Michael S. Tsirkin @ 2018-08-01 22:27 UTC (permalink / raw)
To: Jason Wang
Cc: Jon Olson, willemdebruijn.kernel, caleb.raitto, davem, netdev,
Caleb Raitto
In-Reply-To: <706da951-ed30-85e8-c0aa-cb9ae8b3deb7@redhat.com>
On Mon, Jul 30, 2018 at 02:06:50PM +0800, Jason Wang wrote:
>
>
> On 2018年07月25日 08:17, Jon Olson wrote:
> > On Tue, Jul 24, 2018 at 3:46 PM Michael S. Tsirkin <mst@redhat.com> wrote:
> > > On Tue, Jul 24, 2018 at 06:31:54PM -0400, Willem de Bruijn wrote:
> > > > On Tue, Jul 24, 2018 at 6:23 PM Michael S. Tsirkin <mst@redhat.com> wrote:
> > > > > On Tue, Jul 24, 2018 at 04:52:53PM -0400, Willem de Bruijn wrote:
> > > > > > >From the above linked patch, I understand that there are yet
> > > > > > other special cases in production, such as a hard cap on #tx queues to
> > > > > > 32 regardless of number of vcpus.
> > > > > I don't think upstream kernels have this limit - we can
> > > > > now use vmalloc for higher number of queues.
> > > > Yes. that patch* mentioned it as a google compute engine imposed
> > > > limit. It is exactly such cloud provider imposed rules that I'm
> > > > concerned about working around in upstream drivers.
> > > >
> > > > * for reference, I mean https://patchwork.ozlabs.org/patch/725249/
> > > Yea. Why does GCE do it btw?
> > There are a few reasons for the limit, some historical, some current.
> >
> > Historically we did this because of a kernel limit on the number of
> > TAP queues (in Montreal I thought this limit was 32). To my chagrin,
> > the limit upstream at the time we did it was actually eight. We had
> > increased the limit from eight to 32 internally, and it appears in
> > upstream it has subsequently increased upstream to 256. We no longer
> > use TAP for networking, so that constraint no longer applies for us,
> > but when looking at removing/raising the limit we discovered no
> > workloads that clearly benefited from lifting it, and it also placed
> > more pressure on our virtual networking stack particularly on the Tx
> > side. We left it as-is.
> >
> > In terms of current reasons there are really two. One is memory usage.
> > As you know, virtio-net uses rx/tx pairs, so there's an expectation
> > that the guest will have an Rx queue for every Tx queue. We run our
> > individual virtqueues fairly deep (4096 entries) to give guests a wide
> > time window for re-posting Rx buffers and avoiding starvation on
> > packet delivery. Filling an Rx vring with max-sized mergeable buffers
> > (4096 bytes) is 16MB of GFP_ATOMIC allocations. At 32 queues this can
> > be up to 512MB of memory posted for network buffers. Scaling this to
> > the largest VM GCE offers today (160 VCPUs -- n1-ultramem-160) keeping
> > all of the Rx rings full would (in the large average Rx packet size
> > case) consume up to 2.5 GB(!) of guest RAM. Now, those VMs have 3.8T
> > of RAM available, but I don't believe we've observed a situation where
> > they would have benefited from having 2.5 gigs of buffers posted for
> > incoming network traffic :)
>
> We can work to have async txq and rxq instead of paris if there's a strong
> requirement.
I think the reason we don't is because RX queueing is programmed by TX
packets. It might make sense if we support RX queueing policy that
isn't dependent on TX.
> >
> > The second reason is interrupt related -- as I mentioned above, we
> > have found no workloads that clearly benefit from so many queues, but
> > we have found workloads that degrade. In particular workloads that do
> > a lot of small packet processing but which aren't extremely latency
> > sensitive can achieve higher PPS by taking fewer interrupt across
> > fewer VCPUs due to better batching (this also incurs higher latency,
> > but at the limit the "busy" cores end up suppressing most interrupts
> > and spending most of their cycles farming out work). Memcache is a
> > good example here, particularly if the latency targets for request
> > completion are in the ~milliseconds range (rather than the
> > microseconds we typically strive for with TCP_RR-style workloads).
> >
> > All of that said, we haven't been forthcoming with data (and
> > unfortunately I don't have it handy in a useful form, otherwise I'd
> > simply post it here), so I understand the hesitation to simply run
> > with napi_tx across the board. As Willem said, this patch seemed like
> > the least disruptive way to allow us to continue down the road of
> > "universal" NAPI Tx and to hopefully get data across enough workloads
> > (with VMs small, large, and absurdly large :) to present a compelling
> > argument in one direction or another. As far as I know there aren't
> > currently any NAPI related ethtool commands (based on a quick perusal
> > of ethtool.h)
>
> As I suggest before, maybe we can (ab)use tx-frames-irq.
>
> Thanks
>
> > -- it seems like it would be fairly involved/heavyweight
> > to plumb one solely for this unless NAPI Tx is something many users
> > will want to tune (and for which other drivers would support tuning).
> >
> > --
> > Jon Olson
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: force_napi_tx module param.
From: Michael S. Tsirkin @ 2018-08-01 22:25 UTC (permalink / raw)
To: Willem de Bruijn
Cc: David Miller, caleb.raitto, Jason Wang, Network Development,
Caleb Raitto
In-Reply-To: <CAF=yD-JVj9SLNBftB=ut2-duhi4HQdLBByOHJaZDdavLabD+OA@mail.gmail.com>
On Wed, Aug 01, 2018 at 11:46:14AM -0400, Willem de Bruijn wrote:
> On Tue, Jul 31, 2018 at 8:34 AM Michael S. Tsirkin <mst@redhat.com> wrote:
> >
> > On Sun, Jul 29, 2018 at 05:32:56PM -0400, Willem de Bruijn wrote:
> > > On Sun, Jul 29, 2018 at 12:01 PM David Miller <davem@davemloft.net> wrote:
> > > >
> > > > From: Caleb Raitto <caleb.raitto@gmail.com>
> > > > Date: Mon, 23 Jul 2018 16:11:19 -0700
> > > >
> > > > > From: Caleb Raitto <caraitto@google.com>
> > > > >
> > > > > The driver disables tx napi if it's not certain that completions will
> > > > > be processed affine with tx service.
> > > > >
> > > > > Its heuristic doesn't account for some scenarios where it is, such as
> > > > > when the queue pair count matches the core but not hyperthread count.
> > > > >
> > > > > Allow userspace to override the heuristic. This is an alternative
> > > > > solution to that in the linked patch. That added more logic in the
> > > > > kernel for these cases, but the agreement was that this was better left
> > > > > to user control.
> > > > >
> > > > > Do not expand the existing napi_tx variable to a ternary value,
> > > > > because doing so can break user applications that expect
> > > > > boolean ('Y'/'N') instead of integer output. Add a new param instead.
> > > > >
> > > > > Link: https://patchwork.ozlabs.org/patch/725249/
> > > > > Acked-by: Willem de Bruijn <willemb@google.com>
> > > > > Acked-by: Jon Olson <jonolson@google.com>
> > > > > Signed-off-by: Caleb Raitto <caraitto@google.com>
> > > >
> > > > So I looked into the history surrounding these issues.
> > > >
> > > > First of all, it's always ends up turning out crummy when drivers start
> > > > to set affinities themselves. The worst possible case is to do it
> > > > _conditionally_, and that is exactly what virtio_net is doing.
> > > >
> > > > From the user's perspective, this provides a really bad experience.
> > > >
> > > > So if I have a 32-queue device and there are 32 cpus, you'll do all
> > > > the affinity settings, stopping Irqbalanced from doing anything
> > > > right?
> > > >
> > > > So if I add one more cpu, you'll say "oops, no idea what to do in
> > > > this situation" and not touch the affinities at all?
> > > >
> > > > That makes no sense at all.
> > > >
> > > > If the driver is going to set affinities at all, OWN that decision
> > > > and set it all the time to something reasonable.
> > > >
> > > > Or accept that you shouldn't be touching this stuff in the first place
> > > > and leave the affinities alone.
> > > >
> > > > Right now we're kinda in a situation where the driver has been setting
> > > > affinities in the ncpus==nqueues cases for some time, so we can't stop
> > > > doing it.
> > > >
> > > > Which means we have to set them in all cases to make the user
> > > > experience sane again.
> > > >
> > > > I looked at the linked to patch again:
> > > >
> > > > https://patchwork.ozlabs.org/patch/725249/
> > > >
> > > > And I think the strategy should be made more generic, to get rid of
> > > > the hyperthreading assumptions. I also agree that the "assign
> > > > to first N cpus" logic doesn't make much sense either.
> > > >
> > > > Just distribute across the available cpus evenly, and be done with it.
> > >
> > > Sounds good to me.
> >
> > So e.g. we could set an affinity hint to a group of CPUs that
> > might transmit to this queue.
>
> We also want to set the xps mask for all cpus in the group to this queue.
>
> Is there a benefit over explicitly choosing one cpu from the set, btw?
If only one CPU actually transmits on this queue then probably yes.
And virtio doesn't know whether that's the case.
> I assumed striping. Something along the lines of
>
> int stripe = max_t(int, num_online_cpus() / vi->curr_queue_pairs, 1);
> int vq = 0;
>
> cpumask_clear(xps_mask);
>
> for_each_online_cpu(cpu) {
> cpumask_set_cpu(cpu, xps_mask);
>
> if ((i + 1) % stripe == 0) {
> virtqueue_set_affinity(vi->rq[vq].vq, cpu);
> virtqueue_set_affinity(vi->sq[vq].vq, cpu);
> netif_set_xps_queue(vi->dev, xps_mask, vq);
> cpumask_clear(xps_mask);
> vq++;
> }
> i++;
> }
^ permalink raw reply
* Re: [net-next 07/10] net/mlx5: Enable PCIe buffer congestion handling workaround via devlink
From: Alexander Duyck @ 2018-08-01 22:18 UTC (permalink / raw)
To: Saeed Mahameed
Cc: David S. Miller, Netdev, Jiri Pirko, Jakub Kicinski,
Bjorn Helgaas, Eran Ben Elisha
In-Reply-To: <20180801215255.6642-8-saeedm@mellanox.com>
On Wed, Aug 1, 2018 at 2:52 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> From: Eran Ben Elisha <eranbe@mellanox.com>
>
> Add support for two driver parameters via devlink params interface:
> - Congestion action
> HW mechanism in the PCIe buffer which monitors the amount of
> consumed PCIe buffer per host. This mechanism supports the
> following actions in case of threshold overflow:
> - disabled - NOP (Default)
> - drop
> - mark - Mark CE bit in the CQE of received packet
Any chance you could clarify the differences between "disabled" and
"drop"? I am assuming the "drop" is a head-of-line drop versus the
"disabled" being a incoming packet drop?
Also I still don't see this as necessarily being all that unique of a
feature/issue. Basically being PCIe bus limited is not all that
uncommon of a thing and has existed since the early days of PCI. In
the case of the Intel NICs we just throw a warning and end up dropping
the incoming packets instead of providing the two other options you
have listed.
> - Congestion mode
> - aggressive - Aggressive static trigger threshold (Default)
> - dynamic - Dynamically change the trigger threshold
>
> These driver-specific params enable the NIC HW workaround to handle
> buffer congestion on the current NIC generation.
Is there any documentation anywhere for any of these features? In the
patch set I see you adding interfaces, but I don't see them documented
anywhere.
> Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
> Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
> ---
> .../net/ethernet/mellanox/mlx5/core/devlink.c | 204 +++++++++++++++++-
> 1 file changed, 203 insertions(+), 1 deletion(-)
Ideally there should be some documentation going into the kernel when
you extend the devlink interface at least so that I know how to use
your new interfaces when you define them. Just updating devlink.c
seems like a messy way to do things.
- Alex
^ permalink raw reply
* [net-next 10/10] net/mlx5: Use devlink region_snapshot parameter
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Alex Vesker, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Alex Vesker <valex@mellanox.com>
This parameter enables capturing region snapshot of the crspace
during critical errors. The default value of this parameter is
disabled, it can be enabled using devlink param commands.
It is possible to configure during runtime and also driver init.
Signed-off-by: Alex Vesker <valex@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/devlink.c | 49 +++++++++++++++++++
.../ethernet/mellanox/mlx5/core/diag/crdump.c | 22 +++++++++
.../ethernet/mellanox/mlx5/core/lib/mlx5.h | 2 +
3 files changed, 73 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index ec0ca690839e..4e33049096d0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -2,6 +2,7 @@
/* Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. */
#include <devlink.h>
+#include "lib/mlx5.h"
enum {
MLX5_DEVLINK_MPEGC_FIELD_SELECT_TX_OVERFLOW_DROP_EN = BIT(0),
@@ -288,6 +289,24 @@ static int mlx5_devlink_get_congestion_mode(struct devlink *devlink, u32 id,
return 0;
}
+static int mlx5_devlink_get_crdump_snapshot(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+
+ ctx->val.vbool = mlx5_crdump_is_snapshot_enabled(dev);
+ return 0;
+}
+
+static int mlx5_devlink_set_crdump_snapshot(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+
+ return mlx5_crdump_set_snapshot_enabled(dev, ctx->val.vbool);
+}
+
enum mlx5_devlink_param_id {
MLX5_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
MLX5_DEVLINK_PARAM_ID_CONGESTION_ACTION,
@@ -295,6 +314,11 @@ enum mlx5_devlink_param_id {
};
static const struct devlink_param mlx5_devlink_params[] = {
+ DEVLINK_PARAM_GENERIC(REGION_SNAPSHOT,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME) |
+ BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
+ mlx5_devlink_get_crdump_snapshot,
+ mlx5_devlink_set_crdump_snapshot, NULL),
DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_CONGESTION_ACTION,
"congestion_action",
DEVLINK_PARAM_TYPE_STRING,
@@ -309,6 +333,29 @@ static const struct devlink_param mlx5_devlink_params[] = {
mlx5_devlink_set_congestion_mode, NULL),
};
+static void mlx5_devlink_set_init_value(struct devlink *devlink, u32 param_id,
+ union devlink_param_value init_val)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+ int err;
+
+ err = devlink_param_driverinit_value_set(devlink, param_id, init_val);
+ if (err)
+ dev_warn(&dev->pdev->dev,
+ "devlink set parameter %u value failed (err = %d)",
+ param_id, err);
+}
+
+static void mlx5_devlink_set_params_init_values(struct devlink *devlink)
+{
+ union devlink_param_value value;
+
+ value.vbool = false;
+ mlx5_devlink_set_init_value(devlink,
+ DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
+ value);
+}
+
int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
{
int err;
@@ -324,6 +371,8 @@ int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
goto unregister;
}
+ mlx5_devlink_set_params_init_values(devlink);
+
return 0;
unregister:
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
index fe779e62fc70..94b74b256eaa 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
@@ -44,6 +44,7 @@ static const char *region_cr_space_str = "cr-space";
struct mlx5_fw_crdump {
u32 size;
+ bool snapshot_enable;
struct devlink_region *region_crspace;
};
@@ -125,6 +126,27 @@ int mlx5_crdump_collect(struct mlx5_core_dev *dev)
return ret;
}
+bool mlx5_crdump_is_snapshot_enabled(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+
+ if (mlx5_crdump_enbaled(dev))
+ return priv->health.crdump->snapshot_enable;
+
+ return false;
+}
+
+int mlx5_crdump_set_snapshot_enabled(struct mlx5_core_dev *dev, bool value)
+{
+ struct mlx5_priv *priv = &dev->priv;
+
+ if (!mlx5_crdump_enbaled(dev))
+ return -ENODEV;
+
+ priv->health.crdump->snapshot_enable = value;
+ return 0;
+}
+
int mlx5_crdump_init(struct mlx5_core_dev *dev)
{
struct devlink *devlink = priv_to_devlink(dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
index fbdf332a9174..1533a959b82d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
@@ -41,5 +41,7 @@ int mlx5_core_reserved_gid_alloc(struct mlx5_core_dev *dev, int *gid_index);
void mlx5_core_reserved_gid_free(struct mlx5_core_dev *dev, int gid_index);
int mlx5_crdump_init(struct mlx5_core_dev *dev);
void mlx5_crdump_cleanup(struct mlx5_core_dev *dev);
+bool mlx5_crdump_is_snapshot_enabled(struct mlx5_core_dev *dev);
+int mlx5_crdump_set_snapshot_enabled(struct mlx5_core_dev *dev, bool value);
#endif
--
2.17.0
^ permalink raw reply related
* [net-next 09/10] net/mlx5: Add Crdump FW snapshot support
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Alex Vesker, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Alex Vesker <valex@mellanox.com>
Crdump allows the driver to create a snapshot of the FW PCI
crspace. This is useful in case of catastrophic issues which
require FW reset. The snapshot can be used for later debug.
The snapshot is exposed using devlink, cr-space
address regions are registered on init and snapshots are attached
once a new snapshot is collected by the driver.
Signed-off-by: Alex Vesker <valex@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/Makefile | 3 +-
.../ethernet/mellanox/mlx5/core/diag/crdump.c | 201 ++++++++++++++++++
.../net/ethernet/mellanox/mlx5/core/health.c | 1 +
.../ethernet/mellanox/mlx5/core/lib/mlx5.h | 2 +
.../net/ethernet/mellanox/mlx5/core/main.c | 5 +
include/linux/mlx5/driver.h | 4 +
6 files changed, 215 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index 15f6916efe1b..6ea9e9462c77 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -6,7 +6,8 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o \
mad.o transobj.o vport.o sriov.o fs_cmd.o fs_core.o \
fs_counters.o rl.o lag.o dev.o wq.o lib/gid.o lib/clock.o \
- lib/pci_vsc.o diag/fs_tracepoint.o diag/fw_tracer.o devlink.o
+ lib/pci_vsc.o diag/fs_tracepoint.o diag/fw_tracer.o diag/crdump.o \
+ devlink.o
mlx5_core-$(CONFIG_MLX5_ACCEL) += accel/ipsec.o accel/tls.o
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
new file mode 100644
index 000000000000..fe779e62fc70
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/mlx5/driver.h>
+#include <net/devlink.h>
+#include "mlx5_core.h"
+#include "lib/pci_vsc.h"
+
+#define BAD_ACCESS 0xBADACCE5
+#define MLX5_PROTECTED_CR_SCAN_CRSPACE 0x7
+#define MAX_NUM_OF_DUMPS_TO_STORE (8)
+
+static const char *region_cr_space_str = "cr-space";
+
+struct mlx5_fw_crdump {
+ u32 size;
+ struct devlink_region *region_crspace;
+};
+
+bool mlx5_crdump_enbaled(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+
+ return (!!priv->health.crdump);
+}
+
+static int mlx5_crdump_fill(struct mlx5_core_dev *dev)
+{
+ struct devlink *devlink = priv_to_devlink(dev);
+ struct mlx5_priv *priv = &dev->priv;
+ struct mlx5_fw_crdump *crdump = priv->health.crdump;
+ int i, ret = 0;
+ u32 *cr_data;
+ u32 id;
+
+ cr_data = kvmalloc(crdump->size, GFP_KERNEL);
+ if (!cr_data)
+ return -ENOMEM;
+
+ for (i = 0; i < (crdump->size / 4); i++)
+ cr_data[i] = BAD_ACCESS;
+
+ ret = mlx5_vsc_gw_read_block_fast(dev, cr_data, crdump->size);
+ if (ret <= 0)
+ goto free_data;
+
+ if (crdump->size != ret) {
+ mlx5_core_warn(dev, "failed to read full dump, read %d out of %u\n",
+ ret, crdump->size);
+ ret = -EINVAL;
+ goto free_data;
+ }
+
+ /* Get the available snapshot ID for the dumps */
+ id = devlink_region_shapshot_id_get(devlink);
+ ret = devlink_region_snapshot_create(crdump->region_crspace,
+ crdump->size, (u8 *)cr_data,
+ id, &kvfree);
+ if (ret) {
+ mlx5_core_warn(dev, "crdump: devlink create %s snapshot id %d err %d\n",
+ region_cr_space_str, id, ret);
+ goto free_data;
+ } else {
+ mlx5_core_info(dev, "crdump: added snapshot %d to devlink region %s\n",
+ id, region_cr_space_str);
+ }
+ return 0;
+
+free_data:
+ kvfree(cr_data);
+ return ret;
+}
+
+int mlx5_crdump_collect(struct mlx5_core_dev *dev)
+{
+ int ret = 0;
+
+ if (!mlx5_crdump_enbaled(dev))
+ return -ENODEV;
+
+ ret = mlx5_vsc_gw_lock(dev);
+ if (ret)
+ return ret;
+
+ ret = mlx5_vsc_gw_set_space(dev, MLX5_VSC_SPACE_SCAN_CRSPACE, NULL);
+ if (ret)
+ goto unlock;
+
+ ret = mlx5_crdump_fill(dev);
+ if (ret)
+ goto unlock;
+
+unlock:
+ mlx5_vsc_gw_unlock(dev);
+ return ret;
+}
+
+int mlx5_crdump_init(struct mlx5_core_dev *dev)
+{
+ struct devlink *devlink = priv_to_devlink(dev);
+ struct mlx5_priv *priv = &dev->priv;
+ struct mlx5_fw_crdump *crdump;
+ u32 space_size;
+ int ret;
+
+ if (!mlx5_core_is_pf(dev) || !mlx5_vsc_accessible(dev) ||
+ mlx5_crdump_enbaled(dev))
+ return 0;
+
+ ret = mlx5_vsc_gw_lock(dev);
+ if (ret)
+ return ret;
+
+ /* Check if space is supported and get space size */
+ ret = mlx5_vsc_gw_set_space(dev, MLX5_VSC_SPACE_SCAN_CRSPACE,
+ &space_size);
+ if (ret) {
+ /* Unlock and mask error since space is not supported */
+ mlx5_vsc_gw_unlock(dev);
+ return 0;
+ }
+
+ if (space_size == 0) {
+ mlx5_core_warn(dev, "Invalid Crspace size, zero\n");
+ mlx5_vsc_gw_unlock(dev);
+ return -EINVAL;
+ }
+
+ ret = mlx5_vsc_gw_unlock(dev);
+ if (ret)
+ return ret;
+
+ crdump = kzalloc(sizeof(*crdump), GFP_KERNEL);
+ if (!crdump)
+ return -ENOMEM;
+
+ /* Create cr-space region */
+ crdump->size = space_size;
+ crdump->region_crspace =
+ devlink_region_create(devlink,
+ region_cr_space_str,
+ MAX_NUM_OF_DUMPS_TO_STORE,
+ space_size);
+ if (IS_ERR(crdump->region_crspace)) {
+ mlx5_core_warn(dev,
+ "crdump: create devlink region %s err %ld\n",
+ region_cr_space_str,
+ PTR_ERR(crdump->region_crspace));
+ ret = PTR_ERR(crdump->region_crspace);
+ goto free_crdump;
+ }
+ priv->health.crdump = crdump;
+ return 0;
+
+free_crdump:
+ kfree(crdump);
+ return ret;
+}
+
+void mlx5_crdump_cleanup(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ struct mlx5_fw_crdump *crdump = priv->health.crdump;
+
+ if (!crdump)
+ return;
+
+ devlink_region_destroy(crdump->region_crspace);
+ kfree(crdump);
+ priv->health.crdump = NULL;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index db9e39fdc33e..10ac6a98ea96 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -390,6 +390,7 @@ int mlx5_health_init(struct mlx5_core_dev *dev)
INIT_WORK(&health->work, health_care);
INIT_DELAYED_WORK(&health->recover_work, health_recover);
mlx5_vsc_init(dev);
+ health->crdump = NULL;
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
index 7550b1cc8c6a..fbdf332a9174 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
@@ -39,5 +39,7 @@ int mlx5_core_reserve_gids(struct mlx5_core_dev *dev, unsigned int count);
void mlx5_core_unreserve_gids(struct mlx5_core_dev *dev, unsigned int count);
int mlx5_core_reserved_gid_alloc(struct mlx5_core_dev *dev, int *gid_index);
void mlx5_core_reserved_gid_free(struct mlx5_core_dev *dev, int gid_index);
+int mlx5_crdump_init(struct mlx5_core_dev *dev);
+void mlx5_crdump_cleanup(struct mlx5_core_dev *dev);
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 7a1ddf96f065..f2dd54accd0a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1450,6 +1450,10 @@ static int init_one(struct pci_dev *pdev,
if (err)
goto clean_load;
+ err = mlx5_crdump_init(dev);
+ if (err)
+ dev_err(&pdev->dev, "mlx5_crdump_init failed with error code %d\n", err);
+
pci_save_state(pdev);
return 0;
@@ -1476,6 +1480,7 @@ static void remove_one(struct pci_dev *pdev)
struct devlink *devlink = priv_to_devlink(dev);
struct mlx5_priv *priv = &dev->priv;
+ mlx5_crdump_cleanup(dev);
mlx5_devlink_unregister(devlink);
mlx5_unregister_device(dev);
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 6690875b368b..52744065924a 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -52,6 +52,7 @@
#include <linux/mlx5/srq.h>
#include <linux/timecounter.h>
#include <linux/ptp_clock_kernel.h>
+#include <net/devlink.h>
enum {
MLX5_BOARD_ID_LEN = 64,
@@ -528,6 +529,8 @@ struct mlx5_sq_bfreg {
unsigned int offset;
};
+struct mlx5_fw_crdump;
+
struct mlx5_core_health {
struct health_buffer __iomem *health;
__be32 __iomem *health_counter;
@@ -542,6 +545,7 @@ struct mlx5_core_health {
struct work_struct work;
struct delayed_work recover_work;
u32 vsc_addr;
+ struct mlx5_fw_crdump *crdump;
};
struct mlx5_qp_table {
--
2.17.0
^ permalink raw reply related
* [net-next 07/10] net/mlx5: Enable PCIe buffer congestion handling workaround via devlink
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Eran Ben Elisha, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Eran Ben Elisha <eranbe@mellanox.com>
Add support for two driver parameters via devlink params interface:
- Congestion action
HW mechanism in the PCIe buffer which monitors the amount of
consumed PCIe buffer per host. This mechanism supports the
following actions in case of threshold overflow:
- disabled - NOP (Default)
- drop
- mark - Mark CE bit in the CQE of received packet
- Congestion mode
- aggressive - Aggressive static trigger threshold (Default)
- dynamic - Dynamically change the trigger threshold
These driver-specific params enable the NIC HW workaround to handle
buffer congestion on the current NIC generation.
Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/devlink.c | 204 +++++++++++++++++-
1 file changed, 203 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index e3a5de6b4ee7..ec0ca690839e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -126,12 +126,214 @@ static int mlx5_devlink_query_tx_overflow_sense(struct mlx5_core_dev *mdev,
return 0;
}
+static const char *const action_to_str[] = {
+ [MLX5_DEVLINK_CONGESTION_ACTION_DISABLED] = "disabled",
+ [MLX5_DEVLINK_CONGESTION_ACTION_DROP] = "drop",
+ [MLX5_DEVLINK_CONGESTION_ACTION_MARK] = "mark"
+};
+
+static const char *mlx5_devlink_congestion_action_to_str(int action)
+{
+ if (action > MLX5_DEVLINK_CONGESTION_ACTION_MAX) {
+ WARN_ON(1);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return action_to_str[action];
+}
+
+static int mlx5_devlink_str_to_congestion_action(const char *str, u8 *action)
+{
+ int i;
+
+ for (i = 0; i <= MLX5_DEVLINK_CONGESTION_ACTION_MAX; i++) {
+ if (!strcmp(str, action_to_str[i])) {
+ *action = i;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int mlx5_devlink_set_congestion_action(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+ u8 max = MLX5_DEVLINK_CONGESTION_ACTION_MAX;
+ u8 congestion_action;
+ u8 sense;
+ int err;
+
+ if (!MLX5_CAP_MCAM_FEATURE(dev, mark_tx_action_cqe) &&
+ !MLX5_CAP_MCAM_FEATURE(dev, mark_tx_action_cnp))
+ max = MLX5_DEVLINK_CONGESTION_ACTION_MARK - 1;
+
+ err = mlx5_devlink_str_to_congestion_action(ctx->val.vstr,
+ &congestion_action);
+ if (err)
+ return err;
+
+ if (congestion_action > max) {
+ NL_SET_ERR_MSG(extack, "Requested congestion action is not supported on current device/FW");
+ return -EINVAL;
+ }
+
+ err = mlx5_devlink_query_tx_overflow_sense(dev, &sense);
+ if (err)
+ return err;
+
+ if (congestion_action == MLX5_DEVLINK_CONGESTION_ACTION_DISABLED &&
+ sense != MLX5_DEVLINK_CONGESTION_MODE_AGGRESSIVE) {
+ NL_SET_ERR_MSG(extack, "Congestion action \"disabled\" is allowed only while mode is configured to aggressive");
+ return -EINVAL;
+ }
+
+ return mlx5_devlink_set_tx_lossy_overflow(dev, congestion_action);
+}
+
+static int mlx5_devlink_get_congestion_action(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+ u8 congestion_action;
+ const char *val;
+ int err;
+
+ err = mlx5_devlink_query_tx_lossy_overflow(dev, &congestion_action);
+ if (err)
+ return err;
+
+ val = mlx5_devlink_congestion_action_to_str(congestion_action);
+ if (IS_ERR(val))
+ return PTR_ERR(val);
+
+ devlink_param_value_str_fill(&ctx->val, val);
+ return 0;
+}
+
+static const char *const mode_to_str[] = {
+ [MLX5_DEVLINK_CONGESTION_MODE_AGGRESSIVE] = "aggressive",
+ [MLX5_DEVLINK_CONGESTION_MODE_DYNAMIC_ADJUSTMENT] = "dynamic"
+};
+
+static const char *mlx5_devlink_congestion_mode_to_str(int mode)
+{
+ if (mode > MLX5_DEVLINK_CONGESTION_MODE_MAX) {
+ WARN_ON(1);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return mode_to_str[mode];
+}
+
+static int mlx5_devlink_str_to_congestion_mode(const char *str, u8 *mode)
+{
+ int i;
+
+ for (i = 0; i <= MLX5_DEVLINK_CONGESTION_MODE_MAX; i++) {
+ if (!strcmp(str, mode_to_str[i])) {
+ *mode = i;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int mlx5_devlink_set_congestion_mode(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+ u8 tx_lossy_overflow, congestion_mode;
+ int err;
+
+ err = mlx5_devlink_str_to_congestion_mode(ctx->val.vstr,
+ &congestion_mode);
+ if (err)
+ return err;
+
+ err = mlx5_devlink_query_tx_lossy_overflow(dev, &tx_lossy_overflow);
+ if (err)
+ return err;
+
+ if (congestion_mode != MLX5_DEVLINK_CONGESTION_MODE_AGGRESSIVE &&
+ tx_lossy_overflow == MLX5_DEVLINK_CONGESTION_ACTION_DISABLED) {
+ NL_SET_ERR_MSG(extack, "Congestion mode must be aggressive while congestion action is configured to \"disabled\"");
+ return -EINVAL;
+ }
+
+ return mlx5_devlink_set_tx_overflow_sense(dev, congestion_mode);
+}
+
+static int mlx5_devlink_get_congestion_mode(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
+ u8 congestion_mode;
+ const char *val;
+ int err;
+
+ err = mlx5_devlink_query_tx_overflow_sense(dev, &congestion_mode);
+ if (err)
+ return err;
+
+ val = mlx5_devlink_congestion_mode_to_str(congestion_mode);
+ if (IS_ERR(val))
+ return PTR_ERR(val);
+
+ devlink_param_value_str_fill(&ctx->val, val);
+ return 0;
+}
+
+enum mlx5_devlink_param_id {
+ MLX5_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+ MLX5_DEVLINK_PARAM_ID_CONGESTION_ACTION,
+ MLX5_DEVLINK_PARAM_ID_CONGESTION_MODE,
+};
+
+static const struct devlink_param mlx5_devlink_params[] = {
+ DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_CONGESTION_ACTION,
+ "congestion_action",
+ DEVLINK_PARAM_TYPE_STRING,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+ mlx5_devlink_get_congestion_action,
+ mlx5_devlink_set_congestion_action, NULL),
+ DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_CONGESTION_MODE,
+ "congestion_mode",
+ DEVLINK_PARAM_TYPE_STRING,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+ mlx5_devlink_get_congestion_mode,
+ mlx5_devlink_set_congestion_mode, NULL),
+};
+
int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
{
- return devlink_register(devlink, dev);
+ int err;
+
+ err = devlink_register(devlink, dev);
+ if (err)
+ return err;
+
+ err = devlink_params_register(devlink, mlx5_devlink_params,
+ ARRAY_SIZE(mlx5_devlink_params));
+ if (err) {
+ dev_err(dev, "devlink_params_register failed\n");
+ goto unregister;
+ }
+
+ return 0;
+
+unregister:
+ devlink_unregister(devlink);
+ return err;
}
void mlx5_devlink_unregister(struct devlink *devlink)
{
+ devlink_params_unregister(devlink, mlx5_devlink_params,
+ ARRAY_SIZE(mlx5_devlink_params));
devlink_unregister(devlink);
}
--
2.17.0
^ permalink raw reply related
* [net-next 08/10] net/mlx5: Add Vendor Specific Capability access gateway
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Alex Vesker, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Alex Vesker <valex@mellanox.com>
The Vendor Specific Capability (VSC) is used to activate a gateway
interfacing with the device. The gateway is used to read or write
device configurations, which are organized in different domains (spaces).
A configuration access may result in multiple actions, reads, writes.
Example usages are accessing the Crspace domain to read the crspace or
locking a device semaphore using the Semaphore domain.
Signed-off-by: Alex Vesker <valex@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/Makefile | 2 +-
.../net/ethernet/mellanox/mlx5/core/health.c | 2 +
.../ethernet/mellanox/mlx5/core/lib/pci_vsc.c | 320 ++++++++++++++++++
.../ethernet/mellanox/mlx5/core/lib/pci_vsc.h | 56 +++
include/linux/mlx5/driver.h | 1 +
5 files changed, 380 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index 0be5bf93f33b..15f6916efe1b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -6,7 +6,7 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o \
mad.o transobj.o vport.o sriov.o fs_cmd.o fs_core.o \
fs_counters.o rl.o lag.o dev.o wq.o lib/gid.o lib/clock.o \
- diag/fs_tracepoint.o diag/fw_tracer.o devlink.o
+ lib/pci_vsc.o diag/fs_tracepoint.o diag/fw_tracer.o devlink.o
mlx5_core-$(CONFIG_MLX5_ACCEL) += accel/ipsec.o accel/tls.o
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index d39b0b7011b2..db9e39fdc33e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -38,6 +38,7 @@
#include <linux/mlx5/driver.h>
#include <linux/mlx5/cmd.h>
#include "mlx5_core.h"
+#include "lib/pci_vsc.h"
enum {
MLX5_HEALTH_POLL_INTERVAL = 2 * HZ,
@@ -388,6 +389,7 @@ int mlx5_health_init(struct mlx5_core_dev *dev)
spin_lock_init(&health->wq_lock);
INIT_WORK(&health->work, health_care);
INIT_DELAYED_WORK(&health->recover_work, health_recover);
+ mlx5_vsc_init(dev);
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
new file mode 100644
index 000000000000..cfc2eebbf7c5
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/pci.h>
+#include "mlx5_core.h"
+#include "pci_vsc.h"
+
+#define MLX5_EXTRACT_C(source, offset, size) \
+ ((((unsigned)(source)) >> (offset)) & MLX5_ONES32(size))
+#define MLX5_EXTRACT(src, start, len) \
+ (((len) == 32) ? (src) : MLX5_EXTRACT_C(src, start, len))
+#define MLX5_ONES32(size) \
+ ((size) ? (0xffffffff >> (32 - (size))) : 0)
+#define MLX5_MASK32(offset, size) \
+ (MLX5_ONES32(size) << (offset))
+#define MLX5_MERGE_C(rsrc1, rsrc2, start, len) \
+ ((((rsrc2) << (start)) & (MLX5_MASK32((start), (len)))) | \
+ ((rsrc1) & (~MLX5_MASK32((start), (len)))))
+#define MLX5_MERGE(rsrc1, rsrc2, start, len) \
+ (((len) == 32) ? (rsrc2) : MLX5_MERGE_C(rsrc1, rsrc2, start, len))
+
+#define VSC_MAX_RETRIES 2048
+
+enum {
+ MLX5_VSC_UNLOCK,
+ MLX5_VSC_LOCK,
+};
+
+enum {
+ VSC_CTRL_OFFSET = 0x4,
+ VSC_COUNTER_OFFSET = 0x8,
+ VSC_SEMAPHORE_OFFSET = 0xc,
+ VSC_ADDR_OFFSET = 0x10,
+ VSC_DATA_OFFSET = 0x14,
+
+ VSC_FLAG_BIT_OFFS = 31,
+ VSC_FLAG_BIT_LEN = 1,
+
+ VSC_SYND_BIT_OFFS = 30,
+ VSC_SYND_BIT_LEN = 1,
+
+ VSC_ADDR_BIT_OFFS = 0,
+ VSC_ADDR_BIT_LEN = 30,
+
+ VSC_SPACE_BIT_OFFS = 0,
+ VSC_SPACE_BIT_LEN = 16,
+
+ VSC_SIZE_VLD_BIT_OFFS = 28,
+ VSC_SIZE_VLD_BIT_LEN = 1,
+
+ VSC_STATUS_BIT_OFFS = 29,
+ VSC_STATUS_BIT_LEN = 3,
+};
+
+int mlx5_vsc_init(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+
+ priv->health.vsc_addr = pci_find_capability(dev->pdev,
+ PCI_CAP_ID_VNDR);
+ if (!priv->health.vsc_addr)
+ mlx5_core_warn(dev, "Failed to get valid vendor specific ID\n");
+
+ return 0;
+}
+
+int mlx5_vsc_gw_lock(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ u32 counter = 0;
+ int retries = 0;
+ u32 lock_val;
+ int ret;
+
+ do {
+ if (retries > VSC_MAX_RETRIES)
+ return -EBUSY;
+
+ /* Check if semaphore is already locked */
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_SEMAPHORE_OFFSET,
+ &lock_val);
+ if (ret)
+ return ret;
+
+ if (lock_val) {
+ retries++;
+ usleep_range(1000, 2000);
+ continue;
+ }
+
+ /*
+ * Read and write counter value, if written value is
+ * the same, semaphore was acquired successfully.
+ */
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_COUNTER_OFFSET,
+ &counter);
+ if (ret)
+ return ret;
+
+ ret = pci_write_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_SEMAPHORE_OFFSET,
+ counter);
+ if (ret)
+ return ret;
+
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_SEMAPHORE_OFFSET,
+ &lock_val);
+ if (ret)
+ return ret;
+
+ retries++;
+ } while (counter != lock_val);
+
+ return 0;
+}
+
+int mlx5_vsc_gw_unlock(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ int ret;
+
+ ret = pci_write_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_SEMAPHORE_OFFSET,
+ MLX5_VSC_UNLOCK);
+ return ret;
+}
+
+int mlx5_vsc_gw_set_space(struct mlx5_core_dev *dev, u16 space,
+ u32 *ret_space_size)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ int ret;
+ u32 val;
+
+ if (!mlx5_vsc_accessible(dev))
+ return -EINVAL;
+
+ if (ret_space_size)
+ *ret_space_size = 0;
+
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_CTRL_OFFSET,
+ &val);
+ if (ret)
+ goto out;
+
+ val = MLX5_MERGE(val, space, VSC_SPACE_BIT_OFFS, VSC_SPACE_BIT_LEN);
+ ret = pci_write_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_CTRL_OFFSET,
+ val);
+ if (ret)
+ goto out;
+
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_CTRL_OFFSET,
+ &val);
+ if (ret)
+ goto out;
+
+ if (MLX5_EXTRACT(val, VSC_STATUS_BIT_OFFS, VSC_STATUS_BIT_LEN) == 0)
+ return -EINVAL;
+
+ /* Get space max address if indicated by size valid bit */
+ if (ret_space_size &&
+ MLX5_EXTRACT(val, VSC_SIZE_VLD_BIT_OFFS, VSC_SIZE_VLD_BIT_LEN)) {
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_ADDR_OFFSET,
+ &val);
+ if (ret) {
+ mlx5_core_warn(dev, "Failed to get max space size\n");
+ goto out;
+ }
+ *ret_space_size = MLX5_EXTRACT(val, VSC_ADDR_BIT_OFFS,
+ VSC_ADDR_BIT_LEN);
+ }
+ return 0;
+
+out:
+ return ret;
+}
+
+static int mlx5_vsc_wait_on_flag(struct mlx5_core_dev *dev, u8 expected_val)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ int retries = 0;
+ u32 flag;
+ int ret;
+
+ do {
+ if (retries > VSC_MAX_RETRIES)
+ return -EBUSY;
+
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_ADDR_OFFSET,
+ &flag);
+ flag = MLX5_EXTRACT(flag, VSC_FLAG_BIT_OFFS, VSC_FLAG_BIT_LEN);
+ retries++;
+
+ if ((retries & 0xf) == 0)
+ usleep_range(1000, 2000);
+
+ } while (flag != expected_val);
+
+ return 0;
+}
+
+static int mlx5_vsc_gw_read(struct mlx5_core_dev *dev, unsigned int address,
+ u32 *data)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ int ret;
+
+ if (MLX5_EXTRACT(address, VSC_SYND_BIT_OFFS,
+ VSC_FLAG_BIT_LEN + VSC_SYND_BIT_LEN))
+ return -EINVAL;
+
+ ret = pci_write_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_ADDR_OFFSET,
+ address);
+ if (ret)
+ goto out;
+
+ ret = mlx5_vsc_wait_on_flag(dev, 1);
+ if (ret)
+ goto out;
+
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_DATA_OFFSET,
+ data);
+out:
+ return ret;
+}
+
+static int mlx5_vsc_gw_read_fast(struct mlx5_core_dev *dev,
+ unsigned int read_addr,
+ unsigned int *next_read_addr,
+ u32 *data)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ int ret;
+
+ ret = mlx5_vsc_gw_read(dev, read_addr, data);
+ if (ret)
+ goto out;
+
+ ret = pci_read_config_dword(dev->pdev,
+ priv->health.vsc_addr +
+ VSC_ADDR_OFFSET,
+ next_read_addr);
+ if (ret)
+ goto out;
+
+ *next_read_addr = MLX5_EXTRACT(*next_read_addr, VSC_ADDR_BIT_OFFS,
+ VSC_ADDR_BIT_LEN);
+
+ if (*next_read_addr <= read_addr)
+ ret = EINVAL;
+out:
+ return ret;
+}
+
+int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data,
+ int length)
+{
+ unsigned int next_read_addr = 0;
+ unsigned int read_addr = 0;
+
+ while (read_addr < length) {
+ if (mlx5_vsc_gw_read_fast(dev, read_addr, &next_read_addr,
+ &data[(read_addr >> 2)]))
+ return read_addr;
+
+ read_addr = next_read_addr;
+ }
+ return length;
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h
new file mode 100644
index 000000000000..af10bce44692
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __MLX5_PCI_VSC_H__
+#define __MLX5_PCI_VSC_H__
+
+enum {
+ MLX5_VSC_SPACE_SCAN_CRSPACE = 0x7,
+};
+
+int mlx5_vsc_init(struct mlx5_core_dev *dev);
+void mlx5_vsc_cleanup(struct mlx5_core_dev *dev);
+int mlx5_vsc_gw_lock(struct mlx5_core_dev *dev);
+int mlx5_vsc_gw_unlock(struct mlx5_core_dev *dev);
+int mlx5_vsc_gw_set_space(struct mlx5_core_dev *dev, u16 space,
+ u32 *ret_space_size);
+int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data,
+ int length);
+
+static inline bool mlx5_vsc_accessible(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+
+ return (!!priv->health.vsc_addr);
+}
+
+#endif /* __MLX5_PCI_VSC_H__ */
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 54f385cc8811..6690875b368b 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -541,6 +541,7 @@ struct mlx5_core_health {
unsigned long flags;
struct work_struct work;
struct delayed_work recover_work;
+ u32 vsc_addr;
};
struct mlx5_qp_table {
--
2.17.0
^ permalink raw reply related
* [net-next 06/10] net/mlx5: Add MPEGC register configuration functionality
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Eran Ben Elisha, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Eran Ben Elisha <eranbe@mellanox.com>
MPEGC register is used to configure and access the PCIe general
configuration.
Expose set/get for TX lossy overflow and TX overflow sense which use the
MPEGC register. These will be used in a downstream patch via devlink
params.
Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/devlink.c | 123 ++++++++++++++++++
.../net/ethernet/mellanox/mlx5/core/devlink.h | 1 +
2 files changed, 124 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index 2daf686bcc98..e3a5de6b4ee7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -3,6 +3,129 @@
#include <devlink.h>
+enum {
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_TX_OVERFLOW_DROP_EN = BIT(0),
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_TX_OVERFLOW_SENSE = BIT(3),
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_MARK_TX_ACTION_CQE = BIT(4),
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_MARK_TX_ACTION_CNP = BIT(5),
+};
+
+enum {
+ MLX5_DEVLINK_CONGESTION_ACTION_DISABLED,
+ MLX5_DEVLINK_CONGESTION_ACTION_DROP,
+ MLX5_DEVLINK_CONGESTION_ACTION_MARK,
+ __MLX5_DEVLINK_CONGESTION_ACTION_MAX,
+ MLX5_DEVLINK_CONGESTION_ACTION_MAX = __MLX5_DEVLINK_CONGESTION_ACTION_MAX - 1,
+};
+
+enum {
+ MLX5_DEVLINK_CONGESTION_MODE_AGGRESSIVE,
+ MLX5_DEVLINK_CONGESTION_MODE_DYNAMIC_ADJUSTMENT,
+ __MLX5_DEVLINK_CONGESTION_MODE_MAX,
+ MLX5_DEVLINK_CONGESTION_MODE_MAX = __MLX5_DEVLINK_CONGESTION_MODE_MAX - 1,
+};
+
+static int mlx5_devlink_set_mpegc(struct mlx5_core_dev *mdev, u32 *in,
+ int size_in)
+{
+ u32 out[MLX5_ST_SZ_DW(mpegc_reg)] = {0};
+
+ if (!MLX5_CAP_MCAM_REG(mdev, mpegc))
+ return -EOPNOTSUPP;
+
+ return mlx5_core_access_reg(mdev, in, size_in, out,
+ sizeof(out), MLX5_REG_MPEGC, 0, 1);
+}
+
+static int mlx5_devlink_set_tx_lossy_overflow(struct mlx5_core_dev *mdev,
+ u8 tx_lossy_overflow)
+{
+ u32 in[MLX5_ST_SZ_DW(mpegc_reg)] = {0};
+ u8 field_select = 0;
+
+ if (tx_lossy_overflow == MLX5_DEVLINK_CONGESTION_ACTION_MARK) {
+ if (MLX5_CAP_MCAM_FEATURE(mdev, mark_tx_action_cqe))
+ field_select |=
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_MARK_TX_ACTION_CQE;
+
+ if (MLX5_CAP_MCAM_FEATURE(mdev, mark_tx_action_cnp))
+ field_select |=
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_MARK_TX_ACTION_CNP;
+
+ if (!field_select)
+ return -EOPNOTSUPP;
+ }
+
+ MLX5_SET(mpegc_reg, in, field_select,
+ field_select |
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_TX_OVERFLOW_DROP_EN);
+ MLX5_SET(mpegc_reg, in, tx_lossy_overflow_oper, tx_lossy_overflow);
+ MLX5_SET(mpegc_reg, in, mark_cqe, 0x1);
+ MLX5_SET(mpegc_reg, in, mark_cnp, 0x1);
+
+ return mlx5_devlink_set_mpegc(mdev, in, sizeof(in));
+}
+
+static int mlx5_devlink_set_tx_overflow_sense(struct mlx5_core_dev *mdev,
+ u8 tx_overflow_sense)
+{
+ u32 in[MLX5_ST_SZ_DW(mpegc_reg)] = {0};
+
+ if (!MLX5_CAP_MCAM_FEATURE(mdev, dynamic_tx_overflow))
+ return -EOPNOTSUPP;
+
+ MLX5_SET(mpegc_reg, in, field_select,
+ MLX5_DEVLINK_MPEGC_FIELD_SELECT_TX_OVERFLOW_SENSE);
+ MLX5_SET(mpegc_reg, in, tx_overflow_sense, tx_overflow_sense);
+
+ return mlx5_devlink_set_mpegc(mdev, in, sizeof(in));
+}
+
+static int mlx5_devlink_query_mpegc(struct mlx5_core_dev *mdev, u32 *out,
+ int size_out)
+{
+ u32 in[MLX5_ST_SZ_DW(mpegc_reg)] = {0};
+
+ if (!MLX5_CAP_MCAM_REG(mdev, mpegc))
+ return -EOPNOTSUPP;
+
+ return mlx5_core_access_reg(mdev, in, sizeof(in), out,
+ size_out, MLX5_REG_MPEGC, 0, 0);
+}
+
+static int mlx5_devlink_query_tx_lossy_overflow(struct mlx5_core_dev *mdev,
+ u8 *tx_lossy_overflow)
+{
+ u32 out[MLX5_ST_SZ_DW(mpegc_reg)] = {0};
+ int err;
+
+ err = mlx5_devlink_query_mpegc(mdev, out, sizeof(out));
+ if (err)
+ return err;
+
+ *tx_lossy_overflow = MLX5_GET(mpegc_reg, out, tx_lossy_overflow_oper);
+
+ return 0;
+}
+
+static int mlx5_devlink_query_tx_overflow_sense(struct mlx5_core_dev *mdev,
+ u8 *tx_overflow_sense)
+{
+ u32 out[MLX5_ST_SZ_DW(mpegc_reg)] = {0};
+ int err;
+
+ if (!MLX5_CAP_MCAM_FEATURE(mdev, dynamic_tx_overflow))
+ return -EOPNOTSUPP;
+
+ err = mlx5_devlink_query_mpegc(mdev, out, sizeof(out));
+ if (err)
+ return err;
+
+ *tx_overflow_sense = MLX5_GET(mpegc_reg, out, tx_overflow_sense);
+
+ return 0;
+}
+
int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
{
return devlink_register(devlink, dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
index 455bfa4e89c0..cdf09df8293f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
@@ -5,6 +5,7 @@
#define __MLX5_DEVLINK_H__
#include <net/devlink.h>
+#include <linux/mlx5/driver.h>
int mlx5_devlink_register(struct devlink *devlink, struct device *dev);
void mlx5_devlink_unregister(struct devlink *devlink);
--
2.17.0
^ permalink raw reply related
* [net-next 05/10] net/mlx5: Move all devlink related functions calls to devlink.c
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Eran Ben Elisha, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Eran Ben Elisha <eranbe@mellanox.com>
Centralize all devlink related callbacks in one file.
In the downstream patch, some more functionality will be added, this
patch is preparing the driver infrastructure for it.
Currently, move devlink un/register functions calls into this file.
Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 14 ++++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/devlink.h | 12 ++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/main.c | 5 +++--
4 files changed, 30 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/devlink.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/devlink.h
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index f20fda1ced4f..0be5bf93f33b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -6,7 +6,7 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o \
mad.o transobj.o vport.o sriov.o fs_cmd.o fs_core.o \
fs_counters.o rl.o lag.o dev.o wq.o lib/gid.o lib/clock.o \
- diag/fs_tracepoint.o diag/fw_tracer.o
+ diag/fs_tracepoint.o diag/fw_tracer.o devlink.o
mlx5_core-$(CONFIG_MLX5_ACCEL) += accel/ipsec.o accel/tls.o
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
new file mode 100644
index 000000000000..2daf686bcc98
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. */
+
+#include <devlink.h>
+
+int mlx5_devlink_register(struct devlink *devlink, struct device *dev)
+{
+ return devlink_register(devlink, dev);
+}
+
+void mlx5_devlink_unregister(struct devlink *devlink)
+{
+ devlink_unregister(devlink);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
new file mode 100644
index 000000000000..455bfa4e89c0
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. */
+
+#ifndef __MLX5_DEVLINK_H__
+#define __MLX5_DEVLINK_H__
+
+#include <net/devlink.h>
+
+int mlx5_devlink_register(struct devlink *devlink, struct device *dev);
+void mlx5_devlink_unregister(struct devlink *devlink);
+
+#endif /* __MLX5_DEVLINK_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 03b9c6733eed..7a1ddf96f065 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -56,6 +56,7 @@
#include "fs_core.h"
#include "lib/mpfs.h"
#include "eswitch.h"
+#include "devlink.h"
#include "lib/mlx5.h"
#include "fpga/core.h"
#include "fpga/ipsec.h"
@@ -1445,7 +1446,7 @@ static int init_one(struct pci_dev *pdev,
request_module_nowait(MLX5_IB_MOD);
- err = devlink_register(devlink, &pdev->dev);
+ err = mlx5_devlink_register(devlink, &pdev->dev);
if (err)
goto clean_load;
@@ -1475,7 +1476,7 @@ static void remove_one(struct pci_dev *pdev)
struct devlink *devlink = priv_to_devlink(dev);
struct mlx5_priv *priv = &dev->priv;
- devlink_unregister(devlink);
+ mlx5_devlink_unregister(devlink);
mlx5_unregister_device(dev);
if (mlx5_unload_one(dev, priv, true)) {
--
2.17.0
^ permalink raw reply related
* [net-next 04/10] devlink: Add extack messages support to param set
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Moshe Shemesh, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Moshe Shemesh <moshe@mellanox.com>
Add param extack messages support to param->set() function.
This will enable providing clear reasoning to user on setting new value
failure. Note that param->validate() already supports extack messages,
but it is not enough as input validation can pass or even not needed and
still setting new value may fail for some reason, such as device state,
FW support, etc.
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 3 ++-
drivers/net/ethernet/mellanox/mlx4/main.c | 6 ++++--
include/net/devlink.h | 3 ++-
net/core/devlink.c | 7 ++++---
4 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index 7bd96ab4f7c5..97b987f31881 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -91,7 +91,8 @@ static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
}
static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id,
- struct devlink_param_gset_ctx *ctx)
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
{
struct hwrm_nvm_set_variable_input req = {0};
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index d2d59444f562..629a5c2a4971 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -186,7 +186,8 @@ static int mlx4_devlink_ierr_reset_get(struct devlink *devlink, u32 id,
}
static int mlx4_devlink_ierr_reset_set(struct devlink *devlink, u32 id,
- struct devlink_param_gset_ctx *ctx)
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
{
mlx4_internal_err_reset = ctx->val.vbool;
return 0;
@@ -203,7 +204,8 @@ static int mlx4_devlink_crdump_snapshot_get(struct devlink *devlink, u32 id,
}
static int mlx4_devlink_crdump_snapshot_set(struct devlink *devlink, u32 id,
- struct devlink_param_gset_ctx *ctx)
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
{
struct mlx4_priv *priv = devlink_priv(devlink);
struct mlx4_dev *dev = &priv->dev;
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 99efc156a309..84294f4c2580 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -344,7 +344,8 @@ struct devlink_param {
int (*get)(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx);
int (*set)(struct devlink *devlink, u32 id,
- struct devlink_param_gset_ctx *ctx);
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack);
int (*validate)(struct devlink *devlink, u32 id,
union devlink_param_value val,
struct netlink_ext_ack *extack);
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 367564099357..54ba7e55b1de 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -2746,11 +2746,12 @@ static int devlink_param_get(struct devlink *devlink,
static int devlink_param_set(struct devlink *devlink,
const struct devlink_param *param,
- struct devlink_param_gset_ctx *ctx)
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
{
if (!param->set)
return -EOPNOTSUPP;
- return param->set(devlink, param->id, ctx);
+ return param->set(devlink, param->id, ctx, extack);
}
static int
@@ -3112,7 +3113,7 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
return -EOPNOTSUPP;
ctx.val = value;
ctx.cmode = cmode;
- err = devlink_param_set(devlink, param, &ctx);
+ err = devlink_param_set(devlink, param, &ctx, info->extack);
if (err)
return err;
}
--
2.17.0
^ permalink raw reply related
* [net-next 03/10] devlink: Add helper function for safely copy string param
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Moshe Shemesh, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Moshe Shemesh <moshe@mellanox.com>
Devlink string param buffer is allocated at the size of
DEVLINK_PARAM_MAX_STRING_VALUE. Add helper function which makes sure
this size is not exceeded.
Renamed DEVLINK_PARAM_MAX_STRING_VALUE to
__DEVLINK_PARAM_MAX_STRING_VALUE to emphasize that it should be used by
devlink only. The driver should use the helper function instead to
verify it doesn't exceed the allowed length.
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
include/net/devlink.h | 12 ++++++++++--
net/core/devlink.c | 19 ++++++++++++++++++-
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index b0e17c025fdc..99efc156a309 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -298,7 +298,7 @@ struct devlink_resource {
#define DEVLINK_RESOURCE_ID_PARENT_TOP 0
-#define DEVLINK_PARAM_MAX_STRING_VALUE 32
+#define __DEVLINK_PARAM_MAX_STRING_VALUE 32
enum devlink_param_type {
DEVLINK_PARAM_TYPE_U8,
DEVLINK_PARAM_TYPE_U16,
@@ -311,7 +311,7 @@ union devlink_param_value {
u8 vu8;
u16 vu16;
u32 vu32;
- char vstr[DEVLINK_PARAM_MAX_STRING_VALUE];
+ char vstr[__DEVLINK_PARAM_MAX_STRING_VALUE];
bool vbool;
};
@@ -553,6 +553,8 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
union devlink_param_value init_val);
void devlink_param_value_changed(struct devlink *devlink, u32 param_id);
+void devlink_param_value_str_fill(union devlink_param_value *dst_val,
+ const char *src);
struct devlink_region *devlink_region_create(struct devlink *devlink,
const char *region_name,
u32 region_max_snapshots,
@@ -789,6 +791,12 @@ devlink_param_value_changed(struct devlink *devlink, u32 param_id)
{
}
+static inline void
+devlink_param_value_str_fill(union devlink_param_value *dst_val,
+ const char *src)
+{
+}
+
static inline struct devlink_region *
devlink_region_create(struct devlink *devlink,
const char *region_name,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 99ad53e8297f..367564099357 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3012,7 +3012,7 @@ devlink_param_value_get_from_info(const struct devlink_param *param,
break;
case DEVLINK_PARAM_TYPE_STRING:
if (nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) >
- DEVLINK_PARAM_MAX_STRING_VALUE)
+ __DEVLINK_PARAM_MAX_STRING_VALUE)
return -EINVAL;
strcpy(value->vstr,
nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
@@ -4614,6 +4614,23 @@ void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
}
EXPORT_SYMBOL_GPL(devlink_param_value_changed);
+/**
+ * devlink_param_value_str_fill - Safely fill-up the string preventing
+ * from overflow of the preallocated buffer
+ *
+ * @dst_val: destination devlink_param_value
+ * @src: source buffer
+ */
+void devlink_param_value_str_fill(union devlink_param_value *dst_val,
+ const char *src)
+{
+ size_t len;
+
+ len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
+ WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
+}
+EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
+
/**
* devlink_region_create - create a new address region
*
--
2.17.0
^ permalink raw reply related
* [net-next 02/10] devlink: Fix param cmode driverinit for string type
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Moshe Shemesh, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Moshe Shemesh <moshe@mellanox.com>
Driverinit configuration mode value is held by devlink to enable the
driver fetch the value after reload command. In case the param type is
string devlink should copy the value from driver string buffer to
devlink string buffer on devlink_param_driverinit_value_set() and
vice-versa on devlink_param_driverinit_value_get().
Fixes: ec01aeb1803e ("devlink: Add support for get/set driverinit value")
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
net/core/devlink.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 61e126c28526..99ad53e8297f 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3102,7 +3102,10 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
return -EOPNOTSUPP;
if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
- param_item->driverinit_value = value;
+ if (param->type == DEVLINK_PARAM_TYPE_STRING)
+ strcpy(param_item->driverinit_value.vstr, value.vstr);
+ else
+ param_item->driverinit_value = value;
param_item->driverinit_value_valid = true;
} else {
if (!param->set)
@@ -4542,7 +4545,10 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
DEVLINK_PARAM_CMODE_DRIVERINIT))
return -EOPNOTSUPP;
- *init_val = param_item->driverinit_value;
+ if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
+ strcpy(init_val->vstr, param_item->driverinit_value.vstr);
+ else
+ *init_val = param_item->driverinit_value;
return 0;
}
@@ -4573,7 +4579,10 @@ int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
DEVLINK_PARAM_CMODE_DRIVERINIT))
return -EOPNOTSUPP;
- param_item->driverinit_value = init_val;
+ if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
+ strcpy(param_item->driverinit_value.vstr, init_val.vstr);
+ else
+ param_item->driverinit_value = init_val;
param_item->driverinit_value_valid = true;
devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW);
--
2.17.0
^ permalink raw reply related
* [pull request][net-next 00/10] Mellanox, mlx5 and devlink updates 2018-07-31
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Saeed Mahameed
Hi Dave,
This series provides devlink parameters updates to both devlink API and
mlx5 driver, it is a 2nd iteration of the dropped patches sent in a previous
mlx5 submission "net/mlx5: Support PCIe buffer congestion handling via
Devlink" to address review comments [1].
Changes from the original series:
- According to the discussion outcome, we are keeping the congestion control
setting as mlx5 device specific for the current HW generation.
- Changed the congestion_mode and congestion action param type to string
- Added patches to fix devlink handling of param type string
- Added a patch which adds extack messages support for param set.
- At the end of this series, I've added yet another mlx5 devlink related
feature, firmware snapshot support.
For more information please see tag log below.
Please pull and let me know if there's any problem.
[1] https://patchwork.ozlabs.org/patch/945996/
Thanks,
Saeed.
---
The following changes since commit e6476c21447c4b17c47e476aade6facf050f31e8:
net: remove bogus RCU annotations on socket.wq (2018-07-31 12:40:22 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git tags/mlx5-updates-2018-08-01
for you to fetch changes up to 2ac6108c65ffcb1e5eab1fba1fd59272604d1c32:
net/mlx5: Use devlink region_snapshot parameter (2018-08-01 14:49:09 -0700)
----------------------------------------------------------------
mlx5-updates-2018-08-01
This series provides devlink parameters updates to both devlink API and
mlx5 driver,
1) Devlink changes: (Moshe Shemesh)
The first two patches fix devlink param infrastructure for string type
params.
The third patch adds a devlink helper function to safely copy string from
driver to devlink.
The forth patch adds extack support for param set.
2) mlx5 specific congestion parameters: (Eran Ben Elisha)
Next three patches add new devlink driver specific params for controlling
congestion action and mode, using string type params and extack messages support.
This congestion mode enables hw workaround in specific devices which is
controlled by devlink driver-specific params. The workaround is device
specific for this NIC generation, the next NIC will not need it.
Congestion parameters:
- Congestion action
HW W/A mechanism in the PCIe buffer which monitors the amount of
consumed PCIe buffer per host. This mechanism supports the
following actions in case of threshold overflow:
- Disabled - NOP (Default)
- Drop
- Mark - Mark CE bit in the CQE of received packet
- Congestion mode
- Aggressive - Aggressive static trigger threshold (Default)
- Dynamic - Dynamically change the trigger threshold
3) mlx5 firmware snapshot support via devlink: (Alex Vesker)
Last three patches, add the support for capturing region snapshot of the
firmware crspace during critical errors, using devlink region_snapshot
parameter.
-Saeed.
----------------------------------------------------------------
Alex Vesker (3):
net/mlx5: Add Vendor Specific Capability access gateway
net/mlx5: Add Crdump FW snapshot support
net/mlx5: Use devlink region_snapshot parameter
Eran Ben Elisha (3):
net/mlx5: Move all devlink related functions calls to devlink.c
net/mlx5: Add MPEGC register configuration functionality
net/mlx5: Enable PCIe buffer congestion handling workaround via devlink
Moshe Shemesh (4):
devlink: Fix param set handling for string type
devlink: Fix param cmode driverinit for string type
devlink: Add helper function for safely copy string param
devlink: Add extack messages support to param set
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 3 +-
drivers/net/ethernet/mellanox/mlx4/main.c | 6 +-
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 3 +-
drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 388 +++++++++++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/devlink.h | 13 +
.../net/ethernet/mellanox/mlx5/core/diag/crdump.c | 223 ++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/health.c | 3 +
drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h | 4 +
.../net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c | 320 +++++++++++++++++
.../net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h | 56 +++
drivers/net/ethernet/mellanox/mlx5/core/main.c | 10 +-
include/linux/mlx5/driver.h | 5 +
include/net/devlink.h | 15 +-
net/core/devlink.c | 44 ++-
14 files changed, 1076 insertions(+), 17 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/devlink.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/devlink.h
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/diag/crdump.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.h
^ permalink raw reply
* [net-next 01/10] devlink: Fix param set handling for string type
From: Saeed Mahameed @ 2018-08-01 21:52 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, Jakub Kicinski, Alexander Duyck,
Bjorn Helgaas, Moshe Shemesh, Saeed Mahameed
In-Reply-To: <20180801215255.6642-1-saeedm@mellanox.com>
From: Moshe Shemesh <moshe@mellanox.com>
In case devlink param type is string, it needs to copy the string value
it got from the input to devlink_param_value.
Fixes: e3b7ca18ad7b ("devlink: Add param set command")
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
include/net/devlink.h | 2 +-
net/core/devlink.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index b9b89d6604d4..b0e17c025fdc 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -311,7 +311,7 @@ union devlink_param_value {
u8 vu8;
u16 vu16;
u32 vu32;
- const char *vstr;
+ char vstr[DEVLINK_PARAM_MAX_STRING_VALUE];
bool vbool;
};
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 65fc366a78a4..61e126c28526 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3014,7 +3014,8 @@ devlink_param_value_get_from_info(const struct devlink_param *param,
if (nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) >
DEVLINK_PARAM_MAX_STRING_VALUE)
return -EINVAL;
- value->vstr = nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
+ strcpy(value->vstr,
+ nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
break;
case DEVLINK_PARAM_TYPE_BOOL:
value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ?
--
2.17.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox