diff options
author | David S. Miller <davem@davemloft.net> | 2016-03-02 00:07:31 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-03-02 00:07:31 +0300 |
commit | 7f66ee41566d00f80ed15c0cec0b237f7af8ac0f (patch) | |
tree | 459917c7636f20843eddce7956b4949bfa28b0c6 /include | |
parent | bd070e212688c0d95c68dfe7d54a5aa2a60a8f11 (diff) | |
parent | 18f1e70c413713f28629ffe6863a2c43248ff7a3 (diff) | |
download | linux-7f66ee41566d00f80ed15c0cec0b237f7af8ac0f.tar.xz |
Merge branch 'devlink'
Jiri Pirko says:
====================
Introduce devlink interface and first drivers to use it
There a is need for some userspace API that would allow to expose things
that are not directly related to any device class like net_device of
ib_device, but rather chip-wide/switch-ASIC-wide stuff.
Use cases:
1) get/set of port type (Ethernet/InfiniBand)
2) setting up port splitters - split port into multiple ones and squash again,
enables usage of splitter cable
3) setting up shared buffers - shared among multiple ports within
one chip (work in progress)
4) configuration of switch wide properties - resources division etc - This will
allow to pass configuration that is unacceptable to be passed as
a module option.
First patch of this set introduces a new generic Netlink based interface,
called "devlink". It is similar to nl80211 model and it is heavily
influenced by it, including the API definition. The devlink introduction patch
implements use cases 1) and 2). Other 2 are in development atm and will
be addressed by follow-ups.
It is very convenient for drivers to use devlink, as you can see in other
patches in this set.
Counterpart for devlink is userspace tool for now called "dl". Command line
interface and outputs are derived from "ip" tool so it should be easy
for users to get used to it.
It is available here as a standalone tool for now:
https://github.com/jpirko/devlink
After this is merge in kernel, I will include the "dl" or "devlink" tool
into iproute2 toolset.
Port type setting example:
myhost:~$ dl help
Usage: dl [ OPTIONS ] OBJECT { COMMAND | help }
where OBJECT := { dev | port | monitor }
OPTIONS := { -v/--verbose }
myhost:~$ dl dev help
Usage: dl dev show [DEV]
myhost:~$ dl dev show
pci/0000:01:00.0
myhost:~$ dl port help
Usage: dl port show [DEV/PORT_INDEX]
Usage: dl port set DEV/PORT_INDEX [ type { eth | ib | auto} ]
Usage: dl port split DEV/PORT_INDEX count
Usage: dl port unsplit DEV/PORT_INDEX
myhost:~$ dl port show
pci/0000:01:00.0/1: type ib ibdev mlx4_0
pci/0000:01:00.0/2: type ib ibdev mlx4_0
myhost:~$ sudo dl port set pci/0000:01:00.0/1 type eth
myhost:~$ dl port show
pci/0000:01:00.0/1: type eth netdev ens4
pci/0000:01:00.0/2: type ib ibdev mlx4_0
myhost:~$ sudo dl port set ens4 type auto
myhost:~$ dl port show
pci/0000:01:00.0/1: type eth(auto) netdev ens4
pci/0000:01:00.0/2: type ib ibdev mlx4_0
Port splitting example:
myswitch:~$ sudo modprobe mlxsw_pci
myswitch:~$ dl port
pci/0000:03:00.0/1: type eth netdev eth0
pci/0000:03:00.0/3: type eth netdev eth1
pci/0000:03:00.0/5: type eth netdev eth2
...
pci/0000:03:00.0/63: type eth netdev eth31
myswitch:~$ sudo dl port split pci/0000:03:00.0/1 2 (or "sudo dl port split eth0 2")
myswitch:~$ dl port
pci/0000:03:00.0/3: type eth netdev eth1
pci/0000:03:00.0/5: type eth netdev eth2
...
pci/0000:03:00.0/63: type eth netdev eth31
pci/0000:03:00.0/1: type eth netdev eth0 split_group 16
pci/0000:03:00.0/2: type eth netdev eth32 split_group 16
myswitch:~$ sudo dl port unsplit pci/0000:03:00.0/1
myswitch:~$ dl port
pci/0000:03:00.0/3: type eth netdev eth1
pci/0000:03:00.0/5: type eth netdev eth2
pci/0000:03:00.0/63: type eth netdev eth31
pci/0000:03:00.0/1: type eth netdev eth0
v2->v3:
patch 1/9
-removed generated devlink index and name, use bus name and dev name as
a handle for all userspace originated commands. Along with that,
remove sysfs stub. Requested by Hannes Sowa.
patch 2/9
-add dev param to devlink_register (api change)
patch 4/9
-add dev param to devlink_register (api change)
patch 9/9
-set port's speed according to width fix by Ido
v1->v2:
patch 1/9
-removed no longer used "devlink_dev" helper
-fix couple of typos and misspells
patch 4/9:
-removed SET_NETDEV_DEV set to devlink dev
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mlx4/driver.h | 3 | ||||
-rw-r--r-- | include/net/devlink.h | 140 | ||||
-rw-r--r-- | include/uapi/linux/devlink.h | 72 |
3 files changed, 215 insertions, 0 deletions
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h index 2e8af001c5da..bd0e7075ea6d 100644 --- a/include/linux/mlx4/driver.h +++ b/include/linux/mlx4/driver.h @@ -33,6 +33,7 @@ #ifndef MLX4_DRIVER_H #define MLX4_DRIVER_H +#include <net/devlink.h> #include <linux/mlx4/device.h> struct mlx4_dev; @@ -89,6 +90,8 @@ int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p); void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port); +struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port); + static inline u64 mlx4_mac_to_u64(u8 *addr) { u64 mac = 0; diff --git a/include/net/devlink.h b/include/net/devlink.h new file mode 100644 index 000000000000..c37d257891d6 --- /dev/null +++ b/include/net/devlink.h @@ -0,0 +1,140 @@ +/* + * include/net/devlink.h - Network physical device Netlink interface + * Copyright (c) 2016 Mellanox Technologies. All rights reserved. + * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef _NET_DEVLINK_H_ +#define _NET_DEVLINK_H_ + +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/gfp.h> +#include <linux/list.h> +#include <linux/netdevice.h> +#include <net/net_namespace.h> +#include <uapi/linux/devlink.h> + +struct devlink_ops; + +struct devlink { + struct list_head list; + struct list_head port_list; + const struct devlink_ops *ops; + struct device *dev; + possible_net_t _net; + char priv[0] __aligned(NETDEV_ALIGN); +}; + +struct devlink_port { + struct list_head list; + struct devlink *devlink; + unsigned index; + bool registered; + enum devlink_port_type type; + enum devlink_port_type desired_type; + void *type_dev; + bool split; + u32 split_group; +}; + +struct devlink_ops { + size_t priv_size; + int (*port_type_set)(struct devlink_port *devlink_port, + enum devlink_port_type port_type); + int (*port_split)(struct devlink *devlink, unsigned int port_index, + unsigned int count); + int (*port_unsplit)(struct devlink *devlink, unsigned int port_index); +}; + +static inline void *devlink_priv(struct devlink *devlink) +{ + BUG_ON(!devlink); + return &devlink->priv; +} + +static inline struct devlink *priv_to_devlink(void *priv) +{ + BUG_ON(!priv); + return container_of(priv, struct devlink, priv); +} + +struct ib_device; + +#if IS_ENABLED(CONFIG_NET_DEVLINK) + +struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size); +int devlink_register(struct devlink *devlink, struct device *dev); +void devlink_unregister(struct devlink *devlink); +void devlink_free(struct devlink *devlink); +int devlink_port_register(struct devlink *devlink, + struct devlink_port *devlink_port, + unsigned int port_index); +void devlink_port_unregister(struct devlink_port *devlink_port); +void devlink_port_type_eth_set(struct devlink_port *devlink_port, + struct net_device *netdev); +void devlink_port_type_ib_set(struct devlink_port *devlink_port, + struct ib_device *ibdev); +void devlink_port_type_clear(struct devlink_port *devlink_port); +void devlink_port_split_set(struct devlink_port *devlink_port, + u32 split_group); + +#else + +static inline struct devlink *devlink_alloc(const struct devlink_ops *ops, + size_t priv_size) +{ + return kzalloc(sizeof(struct devlink) + priv_size, GFP_KERNEL); +} + +static inline int devlink_register(struct devlink *devlink, struct device *dev) +{ + return 0; +} + +static inline void devlink_unregister(struct devlink *devlink) +{ +} + +static inline void devlink_free(struct devlink *devlink) +{ + kfree(devlink); +} + +static inline int devlink_port_register(struct devlink *devlink, + struct devlink_port *devlink_port, + unsigned int port_index) +{ + return 0; +} + +static inline void devlink_port_unregister(struct devlink_port *devlink_port) +{ +} + +static inline void devlink_port_type_eth_set(struct devlink_port *devlink_port, + struct net_device *netdev) +{ +} + +static inline void devlink_port_type_ib_set(struct devlink_port *devlink_port, + struct ib_device *ibdev) +{ +} + +static inline void devlink_port_type_clear(struct devlink_port *devlink_port) +{ +} + +static inline void devlink_port_split_set(struct devlink_port *devlink_port, + u32 split_group) +{ +} + +#endif + +#endif /* _NET_DEVLINK_H_ */ diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h new file mode 100644 index 000000000000..c9fee5781eb1 --- /dev/null +++ b/include/uapi/linux/devlink.h @@ -0,0 +1,72 @@ +/* + * include/uapi/linux/devlink.h - Network physical device Netlink interface + * Copyright (c) 2016 Mellanox Technologies. All rights reserved. + * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _UAPI_LINUX_DEVLINK_H_ +#define _UAPI_LINUX_DEVLINK_H_ + +#define DEVLINK_GENL_NAME "devlink" +#define DEVLINK_GENL_VERSION 0x1 +#define DEVLINK_GENL_MCGRP_CONFIG_NAME "config" + +enum devlink_command { + /* don't change the order or add anything between, this is ABI! */ + DEVLINK_CMD_UNSPEC, + + DEVLINK_CMD_GET, /* can dump */ + DEVLINK_CMD_SET, + DEVLINK_CMD_NEW, + DEVLINK_CMD_DEL, + + DEVLINK_CMD_PORT_GET, /* can dump */ + DEVLINK_CMD_PORT_SET, + DEVLINK_CMD_PORT_NEW, + DEVLINK_CMD_PORT_DEL, + + DEVLINK_CMD_PORT_SPLIT, + DEVLINK_CMD_PORT_UNSPLIT, + + /* add new commands above here */ + + __DEVLINK_CMD_MAX, + DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1 +}; + +enum devlink_port_type { + DEVLINK_PORT_TYPE_NOTSET, + DEVLINK_PORT_TYPE_AUTO, + DEVLINK_PORT_TYPE_ETH, + DEVLINK_PORT_TYPE_IB, +}; + +enum devlink_attr { + /* don't change the order or add anything between, this is ABI! */ + DEVLINK_ATTR_UNSPEC, + + /* bus name + dev name together are a handle for devlink entity */ + DEVLINK_ATTR_BUS_NAME, /* string */ + DEVLINK_ATTR_DEV_NAME, /* string */ + + DEVLINK_ATTR_PORT_INDEX, /* u32 */ + DEVLINK_ATTR_PORT_TYPE, /* u16 */ + DEVLINK_ATTR_PORT_DESIRED_TYPE, /* u16 */ + DEVLINK_ATTR_PORT_NETDEV_IFINDEX, /* u32 */ + DEVLINK_ATTR_PORT_NETDEV_NAME, /* string */ + DEVLINK_ATTR_PORT_IBDEV_NAME, /* string */ + DEVLINK_ATTR_PORT_SPLIT_COUNT, /* u32 */ + DEVLINK_ATTR_PORT_SPLIT_GROUP, /* u32 */ + + /* add new attributes above here, update the policy in devlink.c */ + + __DEVLINK_ATTR_MAX, + DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1 +}; + +#endif /* _UAPI_LINUX_DEVLINK_H_ */ |