Skip to content

Commit

Permalink
Merge branch 'net-dpipe'
Browse files Browse the repository at this point in the history
Jiri Pirko says:

====================
Add support for pipeline debug (dpipe)

Arkadi says:

While doing the hardware offloading process much of the hardware
specifics cannot be presented. An example for such is the routing
LPM algorithm which differ in hardware implementation from the
kernel software implementation. The only information the user receives
is whether specific route is offloaded or not, but he cannot really
understand the underlying implementation nor get the specific statistics
related to that process.

Another example is ACL offload using TC which is commonly implemented
using TCAM memory. Currently there is no capability to gain visibility
into the TCAM structure and to debug suboptimal resource allocation.

This patchset introduces capability for exporting the ASICs pipeline
abstraction via devlink infrastructure, which should serve as an
complementary tool. This infrastructure allows the user to get visibility
into the ASIC by modeling it as a set of match/action tables.

The main objects defined:
Table - abstraction for a single pipeline stage. Contains the
        available match/actions and counter availability.
Entry - entry in a specific table with specific matches/actions
        values and dedicated counter.
Header/field - tuples which describes the tables behavior.

As an example one of the ASIC's L3 blocks will be modeled. The egress
rif (router interface) table is the final step in the L3 pipeline
processing which does match on the internal rif index which was
determined before by the routing logic. The erif table determines
whether to forward or drop the packet and updates the corresponding
rif L3 statistics.

To expose this internal resources a special metadata header will
be introduced that describes the internal information gathered by
the ASIC's pipeline and contains the following fields: rif_port_index,
forward and drop.

Some internal hardware resources have direct mapping to kernel
objects. For example the rif_port_index is mapped to the net-devices
ifindex. By providing this mapping the users gains visibility into
the offloading process.

Follow-up work will include exporting more L3 tables which will give
visibility into the routing process.

First stage is adding support for dpipe in devlink. Next add support
in spectrum driver. Finally implement egress router interface
(erif) table for spectrum ASIC as an example.

---
v1->v2: Please see individual patches
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 29, 2017
2 parents cc628c9 + 2ba5999 commit 2a69ca7
Show file tree
Hide file tree
Showing 13 changed files with 1,988 additions and 2 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlxsw/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_switchdev.o spectrum_router.o \
spectrum_kvdl.o spectrum_acl_tcam.o \
spectrum_acl.o spectrum_flower.o \
spectrum_cnt.o
spectrum_cnt.o spectrum_dpipe.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
mlxsw_minimal-objs := minimal.o
178 changes: 178 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -4125,6 +4125,60 @@ MLXSW_ITEM32(reg, ritr, sp_if_system_port, 0x08, 0, 16);
*/
MLXSW_ITEM32(reg, ritr, sp_if_vid, 0x18, 0, 12);

/* Shared between ingress/egress */
enum mlxsw_reg_ritr_counter_set_type {
/* No Count. */
MLXSW_REG_RITR_COUNTER_SET_TYPE_NO_COUNT = 0x0,
/* Basic. Used for router interfaces, counting the following:
* - Error and Discard counters.
* - Unicast, Multicast and Broadcast counters. Sharing the
* same set of counters for the different type of traffic
* (IPv4, IPv6 and mpls).
*/
MLXSW_REG_RITR_COUNTER_SET_TYPE_BASIC = 0x9,
};

/* reg_ritr_ingress_counter_index
* Counter Index for flow counter.
* Access: RW
*/
MLXSW_ITEM32(reg, ritr, ingress_counter_index, 0x38, 0, 24);

/* reg_ritr_ingress_counter_set_type
* Igress Counter Set Type for router interface counter.
* Access: RW
*/
MLXSW_ITEM32(reg, ritr, ingress_counter_set_type, 0x38, 24, 8);

/* reg_ritr_egress_counter_index
* Counter Index for flow counter.
* Access: RW
*/
MLXSW_ITEM32(reg, ritr, egress_counter_index, 0x3C, 0, 24);

/* reg_ritr_egress_counter_set_type
* Egress Counter Set Type for router interface counter.
* Access: RW
*/
MLXSW_ITEM32(reg, ritr, egress_counter_set_type, 0x3C, 24, 8);

static inline void mlxsw_reg_ritr_counter_pack(char *payload, u32 index,
bool enable, bool egress)
{
enum mlxsw_reg_ritr_counter_set_type set_type;

if (enable)
set_type = MLXSW_REG_RITR_COUNTER_SET_TYPE_BASIC;
else
set_type = MLXSW_REG_RITR_COUNTER_SET_TYPE_NO_COUNT;
mlxsw_reg_ritr_egress_counter_set_type_set(payload, set_type);

if (egress)
mlxsw_reg_ritr_egress_counter_index_set(payload, index);
else
mlxsw_reg_ritr_ingress_counter_index_set(payload, index);
}

static inline void mlxsw_reg_ritr_rif_pack(char *payload, u16 rif)
{
MLXSW_REG_ZERO(ritr, payload);
Expand Down Expand Up @@ -4287,6 +4341,129 @@ static inline void mlxsw_reg_ratr_eth_entry_pack(char *payload,
mlxsw_reg_ratr_eth_destination_mac_memcpy_to(payload, dest_mac);
}

/* RICNT - Router Interface Counter Register
* -----------------------------------------
* The RICNT register retrieves per port performance counters
*/
#define MLXSW_REG_RICNT_ID 0x800B
#define MLXSW_REG_RICNT_LEN 0x100

MLXSW_REG_DEFINE(ricnt, MLXSW_REG_RICNT_ID, MLXSW_REG_RICNT_LEN);

/* reg_ricnt_counter_index
* Counter index
* Access: RW
*/
MLXSW_ITEM32(reg, ricnt, counter_index, 0x04, 0, 24);

enum mlxsw_reg_ricnt_counter_set_type {
/* No Count. */
MLXSW_REG_RICNT_COUNTER_SET_TYPE_NO_COUNT = 0x00,
/* Basic. Used for router interfaces, counting the following:
* - Error and Discard counters.
* - Unicast, Multicast and Broadcast counters. Sharing the
* same set of counters for the different type of traffic
* (IPv4, IPv6 and mpls).
*/
MLXSW_REG_RICNT_COUNTER_SET_TYPE_BASIC = 0x09,
};

/* reg_ricnt_counter_set_type
* Counter Set Type for router interface counter
* Access: RW
*/
MLXSW_ITEM32(reg, ricnt, counter_set_type, 0x04, 24, 8);

enum mlxsw_reg_ricnt_opcode {
/* Nop. Supported only for read access*/
MLXSW_REG_RICNT_OPCODE_NOP = 0x00,
/* Clear. Setting the clr bit will reset the counter value for
* all counters of the specified Router Interface.
*/
MLXSW_REG_RICNT_OPCODE_CLEAR = 0x08,
};

/* reg_ricnt_opcode
* Opcode
* Access: RW
*/
MLXSW_ITEM32(reg, ricnt, op, 0x00, 28, 4);

/* reg_ricnt_good_unicast_packets
* good unicast packets.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, good_unicast_packets, 0x08, 0, 64);

/* reg_ricnt_good_multicast_packets
* good multicast packets.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, good_multicast_packets, 0x10, 0, 64);

/* reg_ricnt_good_broadcast_packets
* good broadcast packets
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, good_broadcast_packets, 0x18, 0, 64);

/* reg_ricnt_good_unicast_bytes
* A count of L3 data and padding octets not including L2 headers
* for good unicast frames.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, good_unicast_bytes, 0x20, 0, 64);

/* reg_ricnt_good_multicast_bytes
* A count of L3 data and padding octets not including L2 headers
* for good multicast frames.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, good_multicast_bytes, 0x28, 0, 64);

/* reg_ritr_good_broadcast_bytes
* A count of L3 data and padding octets not including L2 headers
* for good broadcast frames.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, good_broadcast_bytes, 0x30, 0, 64);

/* reg_ricnt_error_packets
* A count of errored frames that do not pass the router checks.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, error_packets, 0x38, 0, 64);

/* reg_ricnt_discrad_packets
* A count of non-errored frames that do not pass the router checks.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, discard_packets, 0x40, 0, 64);

/* reg_ricnt_error_bytes
* A count of L3 data and padding octets not including L2 headers
* for errored frames.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, error_bytes, 0x48, 0, 64);

/* reg_ricnt_discard_bytes
* A count of L3 data and padding octets not including L2 headers
* for non-errored frames that do not pass the router checks.
* Access: RW
*/
MLXSW_ITEM64(reg, ricnt, discard_bytes, 0x50, 0, 64);

static inline void mlxsw_reg_ricnt_pack(char *payload, u32 index,
enum mlxsw_reg_ricnt_opcode op)
{
MLXSW_REG_ZERO(ricnt, payload);
mlxsw_reg_ricnt_op_set(payload, op);
mlxsw_reg_ricnt_counter_index_set(payload, index);
mlxsw_reg_ricnt_counter_set_type_set(payload,
MLXSW_REG_RICNT_COUNTER_SET_TYPE_BASIC);
}

/* RALTA - Router Algorithmic LPM Tree Allocation Register
* -------------------------------------------------------
* RALTA is used to allocate the LPM trees of the SHSPM method.
Expand Down Expand Up @@ -6026,6 +6203,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(rgcr),
MLXSW_REG(ritr),
MLXSW_REG(ratr),
MLXSW_REG(ricnt),
MLXSW_REG(ralta),
MLXSW_REG(ralst),
MLXSW_REG(raltb),
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_COUNTER_POOL_SIZE,
MLXSW_RES_ID_MAX_SPAN,
MLXSW_RES_ID_COUNTER_SIZE_PACKETS_BYTES,
MLXSW_RES_ID_COUNTER_SIZE_ROUTER_BASIC,
MLXSW_RES_ID_MAX_SYSTEM_PORT,
MLXSW_RES_ID_MAX_LAG,
MLXSW_RES_ID_MAX_LAG_MEMBERS,
Expand Down Expand Up @@ -82,6 +83,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_COUNTER_POOL_SIZE] = 0x2410,
[MLXSW_RES_ID_MAX_SPAN] = 0x2420,
[MLXSW_RES_ID_COUNTER_SIZE_PACKETS_BYTES] = 0x2443,
[MLXSW_RES_ID_COUNTER_SIZE_ROUTER_BASIC] = 0x2449,
[MLXSW_RES_ID_MAX_SYSTEM_PORT] = 0x2502,
[MLXSW_RES_ID_MAX_LAG] = 0x2520,
[MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521,
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "trap.h"
#include "txheader.h"
#include "spectrum_cnt.h"
#include "spectrum_dpipe.h"

static const char mlxsw_sp_driver_name[] = "mlxsw_spectrum";
static const char mlxsw_sp_driver_version[] = "1.0";
Expand Down Expand Up @@ -3339,6 +3340,12 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_counter_pool_init;
}

err = mlxsw_sp_dpipe_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init pipeline debug\n");
goto err_dpipe_init;
}

err = mlxsw_sp_ports_create(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to create ports\n");
Expand All @@ -3348,6 +3355,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
return 0;

err_ports_create:
mlxsw_sp_dpipe_fini(mlxsw_sp);
err_dpipe_init:
mlxsw_sp_counter_pool_fini(mlxsw_sp);
err_counter_pool_init:
mlxsw_sp_acl_fini(mlxsw_sp);
Expand All @@ -3372,6 +3381,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);

mlxsw_sp_ports_remove(mlxsw_sp);
mlxsw_sp_dpipe_fini(mlxsw_sp);
mlxsw_sp_counter_pool_fini(mlxsw_sp);
mlxsw_sp_acl_fini(mlxsw_sp);
mlxsw_sp_span_fini(mlxsw_sp);
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ static struct mlxsw_sp_counter_sub_pool mlxsw_sp_counter_sub_pools[] = {
[MLXSW_SP_COUNTER_SUB_POOL_FLOW] = {
.bank_count = 6,
},
[MLXSW_SP_COUNTER_SUB_POOL_RIF] = {
.bank_count = 2,
}
};

static int mlxsw_sp_counter_pool_validate(struct mlxsw_sp *mlxsw_sp)
Expand Down Expand Up @@ -83,6 +86,12 @@ static int mlxsw_sp_counter_sub_pools_prepare(struct mlxsw_sp *mlxsw_sp)
return -EIO;
sub_pool->entry_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
COUNTER_SIZE_PACKETS_BYTES);
/* Prepare erif pool*/
sub_pool = &mlxsw_sp_counter_sub_pools[MLXSW_SP_COUNTER_SUB_POOL_RIF];
if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, COUNTER_SIZE_ROUTER_BASIC))
return -EIO;
sub_pool->entry_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
COUNTER_SIZE_ROUTER_BASIC);
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

enum mlxsw_sp_counter_sub_pool_id {
MLXSW_SP_COUNTER_SUB_POOL_FLOW,
MLXSW_SP_COUNTER_SUB_POOL_RIF,
};

int mlxsw_sp_counter_alloc(struct mlxsw_sp *mlxsw_sp,
Expand Down
Loading

0 comments on commit 2a69ca7

Please sign in to comment.