Re: [PATCH net-next v2 2/7] net: switchdev: support static FDB addresses
On Wed, Aug 5, 2015 at 10:44 PM, Vivien Didelot wrote: > This patch adds a is_static boolean to the switchdev_obj_fdb structure, > in order to set the ndm_state to either NUD_NOARP or NUD_REACHABLE. > > Signed-off-by: Vivien Didelot > --- > include/net/switchdev.h | 1 + > net/switchdev/switchdev.c | 2 +- > 2 files changed, 2 insertions(+), 1 deletion(-) > > diff --git a/include/net/switchdev.h b/include/net/switchdev.h > index e90e1a0..0e296b8 100644 > --- a/include/net/switchdev.h > +++ b/include/net/switchdev.h > @@ -72,6 +72,7 @@ struct switchdev_obj { > struct switchdev_obj_fdb { /* PORT_FDB */ > u8 addr[ETH_ALEN]; > u16 vid; > + bool is_static; What do you think about changing this to u16 ndm_state? That way, it can be used on input (fdb add) and output (fdb dump), and the driver can privately track the state, kind of like how the bridge keeps is_static, is_local, etc. > } fdb; > } u; > }; > diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c > index 9db87a3..e9d1cac 100644 > --- a/net/switchdev/switchdev.c > +++ b/net/switchdev/switchdev.c > @@ -811,7 +811,7 @@ static int switchdev_port_fdb_dump_cb(struct net_device > *dev, > ndm->ndm_flags = NTF_SELF; > ndm->ndm_type= 0; > ndm->ndm_ifindex = dev->ifindex; > - ndm->ndm_state = NUD_REACHABLE; > + ndm->ndm_state = obj->u.fdb.is_static ? NUD_NOARP : NUD_REACHABLE; > > if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, obj->u.fdb.addr)) > goto nla_put_failure; > -- > 2.4.6 > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v2 0/7] net: dsa: mv88e6xxx: support switchdev FDB objects
This patchset refactors the DSA and mv88e6xxx code to use the switchdev FDB objects. The first two patches add minor but necessary changes to switchdev, the third one implements the switchdev glue in DSA for FDB routines, and the remaining ones refactor the FDB access functions in the mv88e6xxx code. Below is an usage example (ports 0-2 belongs to br0, ports 3-4 belongs to br1): # bridge fdb add 3c:97:0e:11:30:6e dev swp2 # bridge fdb add 3c:97:0e:11:40:78 dev swp3 # bridge fdb add 3c:97:0e:11:50:86 dev swp4 # bridge fdb del 3c:97:0e:11:40:78 dev swp3 # bridge fdb 01:00:5e:00:00:01 dev eth0 self permanent 01:00:5e:00:00:01 dev eth1 self permanent 00:50:d2:10:78:15 dev swp0 master br0 permanent 3c:97:0e:11:30:6e dev swp2 self static 00:50:d2:10:78:15 dev swp3 master br1 permanent 3c:97:0e:11:50:86 dev swp4 self static # cat /sys/kernel/debug/dsa0/atu # DB T/P Vec State Addr # 001 Port 004 e 3c:97:0e:11:30:6e # 004 Port 010 e 3c:97:0e:11:50:86 For the 88E6xxx switches, FIDs 1 to num_ports will be reserved for non-bridged ports and bridge groups, and the remaining will be later used by VLANs. This change is necessary to welcome the support for hardware VLANs (which will follow soon). Changes in v2: - remove ndo_bridge_{get,set,del}link from switchdev/DSA glue code - use ether_addr_copy instead of memcpy for MAC addresses - constify MAC address in port_fdb_{add,del} - split the mv88e6xxx code refactoring into several patches Vivien Didelot (7): net: switchdev: change fdb addr for a byte array net: switchdev: support static FDB addresses net: dsa: add support for switchdev FDB objects net: dsa: mv88e6xxx: extend fid mask net: dsa: mv88e6xxx: rename ATU MAC accessors net: dsa: mv88e6xxx: rework FDB getnext operation net: dsa: mv88e6xxx: rework FDB add/del operations drivers/net/dsa/mv88e6171.c | 6 +- drivers/net/dsa/mv88e6352.c | 6 +- drivers/net/dsa/mv88e6xxx.c | 223 --- drivers/net/dsa/mv88e6xxx.h | 31 +++-- drivers/net/ethernet/rocker/rocker.c | 2 +- include/net/dsa.h| 16 ++- include/net/switchdev.h | 3 +- net/bridge/br_fdb.c | 2 +- net/dsa/slave.c | 218 ++ net/switchdev/switchdev.c| 7 +- 10 files changed, 317 insertions(+), 197 deletions(-) -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v2 1/7] net: switchdev: change fdb addr for a byte array
The address in the switchdev_obj_fdb structure is currently represented as a pointer. Replacing it for a 6-byte array allows switchdev to carry addresses directly read from hardware registers, not stored by the switch chip driver (as in Rocker). Signed-off-by: Vivien Didelot --- drivers/net/ethernet/rocker/rocker.c | 2 +- include/net/switchdev.h | 2 +- net/bridge/br_fdb.c | 2 +- net/switchdev/switchdev.c| 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index 4cd5a71..a5bf809 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c @@ -4543,7 +4543,7 @@ static int rocker_port_fdb_dump(const struct rocker_port *rocker_port, hash_for_each_safe(rocker->fdb_tbl, bkt, tmp, found, entry) { if (found->key.pport != rocker_port->pport) continue; - fdb->addr = found->key.addr; + ether_addr_copy(fdb->addr, found->key.addr); fdb->vid = rocker_port_vlan_to_vid(rocker_port, found->key.vlan_id); err = obj->cb(rocker_port->dev, obj); diff --git a/include/net/switchdev.h b/include/net/switchdev.h index 89da893..e90e1a0 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -70,7 +70,7 @@ struct switchdev_obj { u32 tb_id; } ipv4_fib; struct switchdev_obj_fdb { /* PORT_FDB */ - const unsigned char *addr; + u8 addr[ETH_ALEN]; u16 vid; } fdb; } u; diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 9e9875d..5656b44 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -136,11 +136,11 @@ static void fdb_del_external_learn(struct net_bridge_fdb_entry *f) struct switchdev_obj obj = { .id = SWITCHDEV_OBJ_PORT_FDB, .u.fdb = { - .addr = f->addr.addr, .vid = f->vlan_id, }, }; + ether_addr_copy(obj.u.fdb.addr, f->addr.addr); switchdev_port_obj_del(f->dst->dev, &obj); } diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 33bafa2..9db87a3 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -742,11 +743,11 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], struct switchdev_obj obj = { .id = SWITCHDEV_OBJ_PORT_FDB, .u.fdb = { - .addr = addr, .vid = vid, }, }; + ether_addr_copy(obj.u.fdb.addr, addr); return switchdev_port_obj_add(dev, &obj); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); @@ -769,11 +770,11 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], struct switchdev_obj obj = { .id = SWITCHDEV_OBJ_PORT_FDB, .u.fdb = { - .addr = addr, .vid = vid, }, }; + ether_addr_copy(obj.u.fdb.addr, addr); return switchdev_port_obj_del(dev, &obj); } EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v2 4/7] net: dsa: mv88e6xxx: extend fid mask
The driver currently manages one FID per port (or bridge group), with a mask of DSA_MAX_PORTS bits, where 0 means that the FID is in use. The Marvell 88E6xxx switches support up to 4094 FIDs (from 1 to 0xfff; FID 0 means that multiple address databases are not being used). This patch changes the fid_mask for an fid_bitmap of 4096 bits. >From now on, FIDs 1 to num_ports are reserved for non-bridged ports and bridge groups (a bridge group gets the FID of its first member). The remaining bits will be reserved for VLAN entries. Signed-off-by: Vivien Didelot --- drivers/net/dsa/mv88e6xxx.c | 20 +--- drivers/net/dsa/mv88e6xxx.h | 8 +--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 438c73e..b051576 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1091,7 +1091,7 @@ int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask) ps->bridge_mask[fid] = br_port_mask; if (fid != ps->fid[port]) { - ps->fid_mask |= 1 << ps->fid[port]; + clear_bit(ps->fid[port], ps->fid_bitmap); ps->fid[port] = fid; ret = _mv88e6xxx_update_bridge_config(ds, fid); } @@ -1125,9 +1125,16 @@ int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask) mutex_lock(&ps->smi_mutex); - newfid = __ffs(ps->fid_mask); + newfid = find_next_zero_bit(ps->fid_bitmap, VLAN_N_VID, 1); + if (unlikely(newfid > ps->num_ports)) { + netdev_err(ds->ports[port], "all first %d FIDs are used\n", + ps->num_ports); + ret = -ENOSPC; + goto unlock; + } + ps->fid[port] = newfid; - ps->fid_mask &= ~(1 << newfid); + set_bit(newfid, ps->fid_bitmap); ps->bridge_mask[fid] &= ~(1 << port); ps->bridge_mask[newfid] = 1 << port; @@ -1135,6 +1142,7 @@ int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask) if (!ret) ret = _mv88e6xxx_update_bridge_config(ds, newfid); +unlock: mutex_unlock(&ps->smi_mutex); return ret; @@ -1554,9 +1562,9 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) * ports, and allow each of the 'real' ports to only talk to * the upstream port. */ - fid = __ffs(ps->fid_mask); + fid = port + 1; ps->fid[port] = fid; - ps->fid_mask &= ~(1 << fid); + set_bit(fid, ps->fid_bitmap); if (!dsa_is_cpu_port(ds, port)) ps->bridge_mask[fid] = 1 << port; @@ -1855,8 +1863,6 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds) ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0; - ps->fid_mask = (1 << DSA_MAX_PORTS) - 1; - INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); name = kasprintf(GFP_KERNEL, "dsa%d", ds->index); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 6a66b4b..6d65b99 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -11,6 +11,8 @@ #ifndef __MV88E6XXX_H #define __MV88E6XXX_H +#include + #ifndef UINT64_MAX #define UINT64_MAX (u64)(~((u64)0)) #endif @@ -348,9 +350,9 @@ struct mv88e6xxx_priv_state { /* hw bridging */ - u32 fid_mask; - u8 fid[DSA_MAX_PORTS]; - u16 bridge_mask[DSA_MAX_PORTS]; + DECLARE_BITMAP(fid_bitmap, VLAN_N_VID); /* FIDs 1 to 4095 available */ + u16 fid[DSA_MAX_PORTS]; /* per (non-bridged) port FID */ + u16 bridge_mask[DSA_MAX_PORTS]; /* br groups (indexed by FID) */ unsigned long port_state_update_mask; u8 port_state[DSA_MAX_PORTS]; -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v2 3/7] net: dsa: add support for switchdev FDB objects
Remove the fdb_{add,del,getnext} function pointer in favor of new port_fdb_{add,del,getnext}. Implement the switchdev_port_obj_{add,del,dump} functions in DSA to support the SWITCHDEV_OBJ_PORT_FDB objects. Signed-off-by: Vivien Didelot --- drivers/net/dsa/mv88e6171.c | 3 - drivers/net/dsa/mv88e6352.c | 3 - include/net/dsa.h | 16 ++-- net/dsa/slave.c | 218 +++- 4 files changed, 126 insertions(+), 114 deletions(-) diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 1c78084..cfa21ed 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -116,9 +116,6 @@ struct dsa_switch_driver mv88e6171_switch_driver = { .port_join_bridge = mv88e6xxx_join_bridge, .port_leave_bridge = mv88e6xxx_leave_bridge, .port_stp_update= mv88e6xxx_port_stp_update, - .fdb_add= mv88e6xxx_port_fdb_add, - .fdb_del= mv88e6xxx_port_fdb_del, - .fdb_getnext= mv88e6xxx_port_fdb_getnext, }; MODULE_ALIAS("platform:mv88e6171"); diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index af210ef..eb4630f 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -341,9 +341,6 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .port_join_bridge = mv88e6xxx_join_bridge, .port_leave_bridge = mv88e6xxx_leave_bridge, .port_stp_update= mv88e6xxx_port_stp_update, - .fdb_add= mv88e6xxx_port_fdb_add, - .fdb_del= mv88e6xxx_port_fdb_del, - .fdb_getnext= mv88e6xxx_port_fdb_getnext, }; MODULE_ALIAS("platform:mv88e6172"); diff --git a/include/net/dsa.h b/include/net/dsa.h index fbca63b..091d35f 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -296,12 +296,16 @@ struct dsa_switch_driver { u32 br_port_mask); int (*port_stp_update)(struct dsa_switch *ds, int port, u8 state); - int (*fdb_add)(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid); - int (*fdb_del)(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid); - int (*fdb_getnext)(struct dsa_switch *ds, int port, - unsigned char *addr, bool *is_static); + + /* +* Forwarding database +*/ + int (*port_fdb_add)(struct dsa_switch *ds, int port, u16 vid, + const u8 addr[ETH_ALEN]); + int (*port_fdb_del)(struct dsa_switch *ds, int port, u16 vid, + const u8 addr[ETH_ALEN]); + int (*port_fdb_getnext)(struct dsa_switch *ds, int port, u16 *vid, + u8 addr[ETH_ALEN], bool *is_static); }; void register_switch_driver(struct dsa_switch_driver *type); diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 0010c69..1dbdeaa 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "dsa_priv.h" /* slave mii_bus handling ***/ @@ -200,105 +201,6 @@ out: return 0; } -static int dsa_slave_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], -struct net_device *dev, -const unsigned char *addr, u16 vid, u16 nlm_flags) -{ - struct dsa_slave_priv *p = netdev_priv(dev); - struct dsa_switch *ds = p->parent; - int ret = -EOPNOTSUPP; - - if (ds->drv->fdb_add) - ret = ds->drv->fdb_add(ds, p->port, addr, vid); - - return ret; -} - -static int dsa_slave_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], -struct net_device *dev, -const unsigned char *addr, u16 vid) -{ - struct dsa_slave_priv *p = netdev_priv(dev); - struct dsa_switch *ds = p->parent; - int ret = -EOPNOTSUPP; - - if (ds->drv->fdb_del) - ret = ds->drv->fdb_del(ds, p->port, addr, vid); - - return ret; -} - -static int dsa_slave_fill_info(struct net_device *dev, struct sk_buff *skb, - const unsigned char *addr, u16 vid, - bool is_static, - u32 portid, u32 seq, int type, - unsigned int flags) -{ - struct nlmsghdr *nlh; - struct ndmsg *ndm; - - nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags); - if (!nlh) - return -EMSGSIZE; - - ndm = nlmsg_data(nlh); - ndm->ndm_family = AF_BRIDGE; - ndm->ndm_pad1= 0; - ndm->ndm_pad2= 0; - ndm->ndm_flags = NTF_EXT_LEARNED; - ndm->ndm_type= 0; - ndm->ndm_ifindex = dev-
[PATCH net-next v2 2/7] net: switchdev: support static FDB addresses
This patch adds a is_static boolean to the switchdev_obj_fdb structure, in order to set the ndm_state to either NUD_NOARP or NUD_REACHABLE. Signed-off-by: Vivien Didelot --- include/net/switchdev.h | 1 + net/switchdev/switchdev.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/net/switchdev.h b/include/net/switchdev.h index e90e1a0..0e296b8 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -72,6 +72,7 @@ struct switchdev_obj { struct switchdev_obj_fdb { /* PORT_FDB */ u8 addr[ETH_ALEN]; u16 vid; + bool is_static; } fdb; } u; }; diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 9db87a3..e9d1cac 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -811,7 +811,7 @@ static int switchdev_port_fdb_dump_cb(struct net_device *dev, ndm->ndm_flags = NTF_SELF; ndm->ndm_type= 0; ndm->ndm_ifindex = dev->ifindex; - ndm->ndm_state = NUD_REACHABLE; + ndm->ndm_state = obj->u.fdb.is_static ? NUD_NOARP : NUD_REACHABLE; if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, obj->u.fdb.addr)) goto nla_put_failure; -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v2 5/7] net: dsa: mv88e6xxx: rename ATU MAC accessors
Rename the __mv88e6xxx_{read,write}_addr functions to more explicit _mv88e6xxx_atu_mac_{read,write} functions, which also respect the single underscore convention used in the file (meaning SMI lock must be held). In the meantime, define their MAC address parameters as an array of ETH_ALEN bytes instead of a char pointer. Signed-off-by: Vivien Didelot --- drivers/net/dsa/mv88e6xxx.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index b051576..9dad0a7 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1182,8 +1182,8 @@ int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state) return 0; } -static int __mv88e6xxx_write_addr(struct dsa_switch *ds, - const unsigned char *addr) +static int _mv88e6xxx_atu_mac_write(struct dsa_switch *ds, + const u8 addr[ETH_ALEN]) { int i, ret; @@ -1198,7 +1198,7 @@ static int __mv88e6xxx_write_addr(struct dsa_switch *ds, return 0; } -static int __mv88e6xxx_read_addr(struct dsa_switch *ds, unsigned char *addr) +static int _mv88e6xxx_atu_mac_read(struct dsa_switch *ds, u8 addr[ETH_ALEN]) { int i, ret; @@ -1225,7 +1225,7 @@ static int __mv88e6xxx_port_fdb_cmd(struct dsa_switch *ds, int port, if (ret < 0) return ret; - ret = __mv88e6xxx_write_addr(ds, addr); + ret = _mv88e6xxx_atu_mac_write(ds, addr); if (ret < 0) return ret; @@ -1280,7 +1280,7 @@ static int __mv88e6xxx_port_getnext(struct dsa_switch *ds, int port, if (ret < 0) return ret; - ret = __mv88e6xxx_write_addr(ds, addr); + ret = _mv88e6xxx_atu_mac_write(ds, addr); if (ret < 0) return ret; @@ -1297,7 +1297,7 @@ static int __mv88e6xxx_port_getnext(struct dsa_switch *ds, int port, return -ENOENT; } while (!(((ret >> 4) & 0xff) & (1 << port))); - ret = __mv88e6xxx_read_addr(ds, addr); + ret = _mv88e6xxx_atu_mac_read(ds, addr); if (ret < 0) return ret; @@ -1661,7 +1661,7 @@ static int mv88e6xxx_atu_show_db(struct seq_file *s, struct dsa_switch *ds, unsigned char addr[6]; int ret, data, state; - ret = __mv88e6xxx_write_addr(ds, bcast); + ret = _mv88e6xxx_atu_mac_write(ds, bcast); if (ret < 0) return ret; @@ -1676,7 +1676,7 @@ static int mv88e6xxx_atu_show_db(struct seq_file *s, struct dsa_switch *ds, state = data & GLOBAL_ATU_DATA_STATE_MASK; if (state == GLOBAL_ATU_DATA_STATE_UNUSED) break; - ret = __mv88e6xxx_read_addr(ds, addr); + ret = _mv88e6xxx_atu_mac_read(ds, addr); if (ret < 0) return ret; mv88e6xxx_atu_show_entry(s, dbnum, addr, data); -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v2 7/7] net: dsa: mv88e6xxx: rework FDB add/del operations
Add a low level function for the ATU Load operation, and provide FDB add and delete wrappers functions. Signed-off-by: Vivien Didelot --- drivers/net/dsa/mv88e6171.c | 2 + drivers/net/dsa/mv88e6352.c | 2 + drivers/net/dsa/mv88e6xxx.c | 110 +--- drivers/net/dsa/mv88e6xxx.h | 8 ++-- 4 files changed, 80 insertions(+), 42 deletions(-) diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index b99fa50..735f04c 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -116,6 +116,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = { .port_join_bridge = mv88e6xxx_join_bridge, .port_leave_bridge = mv88e6xxx_leave_bridge, .port_stp_update= mv88e6xxx_port_stp_update, + .port_fdb_add = mv88e6xxx_port_fdb_add, + .port_fdb_del = mv88e6xxx_port_fdb_del, .port_fdb_getnext = mv88e6xxx_port_fdb_getnext, }; diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 0a77135..191fb25 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -341,6 +341,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .port_join_bridge = mv88e6xxx_join_bridge, .port_leave_bridge = mv88e6xxx_leave_bridge, .port_stp_update= mv88e6xxx_port_stp_update, + .port_fdb_add = mv88e6xxx_port_fdb_add, + .port_fdb_del = mv88e6xxx_port_fdb_del, .port_fdb_getnext = mv88e6xxx_port_fdb_getnext, }; diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 6cad168..39203bb 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1214,59 +1214,42 @@ static int _mv88e6xxx_atu_mac_read(struct dsa_switch *ds, u8 addr[ETH_ALEN]) return 0; } -static int __mv88e6xxx_port_fdb_cmd(struct dsa_switch *ds, int port, - const unsigned char *addr, int state) +static int _mv88e6xxx_atu_load(struct dsa_switch *ds, + struct mv88e6xxx_atu_entry *entry) { - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - u8 fid = ps->fid[port]; + u16 reg = 0; int ret; ret = _mv88e6xxx_atu_wait(ds); if (ret < 0) return ret; - ret = _mv88e6xxx_atu_mac_write(ds, addr); + ret = _mv88e6xxx_atu_mac_write(ds, entry->mac); if (ret < 0) return ret; - ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_DATA, - (0x10 << port) | state); - if (ret) - return ret; + if (entry->state != GLOBAL_ATU_DATA_STATE_UNUSED) { + unsigned int mask, shift; - ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_LOAD_DB); + if (entry->trunk) { + reg |= GLOBAL_ATU_DATA_TRUNK; + mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK; + shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT; + } else { + mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK; + shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT; + } - return ret; -} + reg |= (entry->portv_trunkid << shift) & mask; + } -int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid) -{ - int state = is_multicast_ether_addr(addr) ? - GLOBAL_ATU_DATA_STATE_MC_STATIC : - GLOBAL_ATU_DATA_STATE_UC_STATIC; - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; + reg |= entry->state & GLOBAL_ATU_DATA_STATE_MASK; - mutex_lock(&ps->smi_mutex); - ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr, state); - mutex_unlock(&ps->smi_mutex); + ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_DATA, reg); + if (ret < 0) + return ret; - return ret; -} - -int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - - mutex_lock(&ps->smi_mutex); - ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr, - GLOBAL_ATU_DATA_STATE_UNUSED); - mutex_unlock(&ps->smi_mutex); - - return ret; + return _mv88e6xxx_atu_cmd(ds, entry->fid, GLOBAL_ATU_OP_LOAD_DB); } static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid, @@ -1329,6 +1312,57 @@ static int _mv88e6xxx_port_vid_to_fid(struct dsa_switch *ds, int port, u16 vid) return -ENOENT; } +static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port, u16 vid, + const u8 addr[ETH_ALEN], u8 state) +{ + struct mv88e6xxx_atu_entry entry = { 0 }; + int ret; + + r
[PATCH net-next v2 6/7] net: dsa: mv88e6xxx: rework FDB getnext operation
This commit adds a low level _mv88e6xxx_atu_getnext function and helpers to rewrite the mv88e6xxx_port_fdb_getnext operation. A mv88e6xxx_atu_entry structure is added for convenient access to the hardware, and GLOBAL_ATU_FID is defined instead of the raw 0x01 value. The previous implementation did not handle the eventual trunk mapping. If the related bit is set, then the ATU data register would contain the trunk ID, and not the port vector. Check this in the FDB getnext operation and do not handle it (yet). Signed-off-by: Vivien Didelot --- drivers/net/dsa/mv88e6171.c | 1 + drivers/net/dsa/mv88e6352.c | 1 + drivers/net/dsa/mv88e6xxx.c | 97 + drivers/net/dsa/mv88e6xxx.h | 15 ++- 4 files changed, 87 insertions(+), 27 deletions(-) diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index cfa21ed..b99fa50 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -116,6 +116,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = { .port_join_bridge = mv88e6xxx_join_bridge, .port_leave_bridge = mv88e6xxx_leave_bridge, .port_stp_update= mv88e6xxx_port_stp_update, + .port_fdb_getnext = mv88e6xxx_port_fdb_getnext, }; MODULE_ALIAS("platform:mv88e6171"); diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index eb4630f..0a77135 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -341,6 +341,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .port_join_bridge = mv88e6xxx_join_bridge, .port_leave_bridge = mv88e6xxx_leave_bridge, .port_stp_update= mv88e6xxx_port_stp_update, + .port_fdb_getnext = mv88e6xxx_port_fdb_getnext, }; MODULE_ALIAS("platform:mv88e6172"); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 9dad0a7..6cad168 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -964,7 +964,7 @@ static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd) { int ret; - ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid); + ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid); if (ret < 0) return ret; @@ -1269,12 +1269,14 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, return ret; } -static int __mv88e6xxx_port_getnext(struct dsa_switch *ds, int port, - unsigned char *addr, bool *is_static) +static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid, + const u8 addr[ETH_ALEN], + struct mv88e6xxx_atu_entry *entry) { - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - u8 fid = ps->fid[port]; - int ret, state; + struct mv88e6xxx_atu_entry next = { 0 }; + int ret; + + next.fid = fid; ret = _mv88e6xxx_atu_wait(ds); if (ret < 0) @@ -1284,39 +1286,84 @@ static int __mv88e6xxx_port_getnext(struct dsa_switch *ds, int port, if (ret < 0) return ret; - do { - ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_GET_NEXT_DB); - if (ret < 0) - return ret; + ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_GET_NEXT_DB); + if (ret < 0) + return ret; - ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_DATA); - if (ret < 0) - return ret; - state = ret & GLOBAL_ATU_DATA_STATE_MASK; - if (state == GLOBAL_ATU_DATA_STATE_UNUSED) - return -ENOENT; - } while (!(((ret >> 4) & 0xff) & (1 << port))); + ret = _mv88e6xxx_atu_mac_read(ds, next.mac); + if (ret < 0) + return ret; - ret = _mv88e6xxx_atu_mac_read(ds, addr); + ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_DATA); if (ret < 0) return ret; - *is_static = state == (is_multicast_ether_addr(addr) ? - GLOBAL_ATU_DATA_STATE_MC_STATIC : - GLOBAL_ATU_DATA_STATE_UC_STATIC); + next.state = ret & GLOBAL_ATU_DATA_STATE_MASK; + if (next.state != GLOBAL_ATU_DATA_STATE_UNUSED) { + unsigned int mask, shift; + + if (ret & GLOBAL_ATU_DATA_TRUNK) { + next.trunk = true; + mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK; + shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT; + } else { + next.trunk = false; + mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK; + shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT; + } + + next.portv_trunkid = (ret & mask) >> shift; + } + *entry = next; return 0; } -/* ge
Re: rtnl_mutex deadlock?
On Wed, Aug 05, 2015 at 08:59:07PM +0200, Daniel Borkmann wrote: > > Here's a theory and patch below. Herbert, Thomas, does this make any > sense to you resp. sound plausible? ;) Another possibility is the following bug: https://patchwork.ozlabs.org/patch/503374/ It can cause a use-after-free which may lead to corruption of skb state, including the cb buffer. Of course it's a long shot. Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 4/7] Drivers: hv: vmbus: add APIs to register callbacks to process hvsock connection
> From: devel [mailto:driverdev-devel-boun...@linuxdriverproject.org] On Behalf > Of Dexuan Cui > Sent: Thursday, July 30, 2015 18:20 > To: David Miller ; KY Srinivasan > Cc: o...@aepfle.de; gre...@linuxfoundation.org; jasow...@redhat.com; > driverdev-de...@linuxdriverproject.org; linux-ker...@vger.kernel.org; > step...@networkplumber.org; stefa...@redhat.com; netdev@vger.kernel.org; > a...@canonical.com; pebo...@tiscali.nl; dan.carpen...@oracle.com > Subject: RE: [PATCH V4 4/7] Drivers: hv: vmbus: add APIs to register > callbacks to > process hvsock connection > > > From: David Miller > > Sent: Thursday, July 30, 2015 6:27 > > > > From: Dexuan Cui > > Date: Tue, 28 Jul 2015 05:35:11 -0700 > > > > > With the 2 APIs supplied by the VMBus driver, the coming net/hvsock driver > > > can register 2 callbacks and can know when a new hvsock connection is > > > offered by the host, and when a hvsock connection is being closed by the > > > host. > > > > > This is an extremely terrible interface. > > > > It's an opaque hook that allows on registry, and it's solve purpose > > is to allow a backdoor call into a foreign driver in another module. > > > > These are exactly the things we try to avoid. > > Hi David, > Thanks a lot for your reviewing and the suggestion! > > > Why not create a real abstraction where clients register an object, > > that can be contained as a sub-member inside of their own driver > > private, that provides the callback registry mechanism. Hi David, Can you please have a look at my below questions? I like your idea of a real abstraction. Your answer would definitely help me to implement that correctly. > Please pardon me for my inexperience. > Can you please be a bit more specific? > I guess maybe you're referencing a common design pattern in the driver > code, so an example in some existing driver would be the best. :-) > > "clients register an object " -- > does the "clients" mean the hvsock driver? > and the "object" means the 2 callbacks? > > IMHO, here the vmbus driver has to synchronously pass the 2 events > to the hvsock driver, so a "backdoor call into the hvsock driver" is > inevitable anyway? > > e.g., in the path vmbus_process_offer() -> hvsock_process_offer(), the > return value of the latter is important to the former, because on error > the former needs to clean up some internal states of the vmbus driver (that > is, the "goto err_deq_chan"). > > > > That way you can register multiple clients, do things like allow > > AF_PACKET capturing of vmbus traffic, etc. > > I thought AF_PACKET can only capture IP packets or Ethernet frames. > Can it be used to capture AF_UNIX packet? > If yes, I suppose we can consider making it work for AF_HYPERV too, > if people ask for that. > > -- Dexuan Thanks, -- Dexuan -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH for-next V7 00/10] Move RoCE GID management to IB/Core
On Sun, Aug 02, 2015 at 10:56:38AM +0300, Matan Barak wrote: > Indeed this design flaw was introduced when the first legacy verb was > extended. I think that falling back from extended code to legacy code > should be in the uverbs code. ib_uverbs_write will return -ENOSYS only > if both extended and non-extended don't exist. The uverbs command itself > will call the non-extended form if the comp_mask is zero and all > data between legacy size and the given size are zero as well. > What do you think? Yes, that is what I had expected from day 1.. Didn't notice it in the first introduction. Thanks, Jason -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V4 7/7] Drivers: hv: vmbus: disable local interrupt when hvsock's callback is running
> -Original Message- > From: devel [mailto:driverdev-devel-boun...@linuxdriverproject.org] On Behalf > Of Dexuan Cui > Sent: Thursday, July 30, 2015 18:18 > To: David Miller ; KY Srinivasan > Cc: o...@aepfle.de; gre...@linuxfoundation.org; jasow...@redhat.com; > driverdev-de...@linuxdriverproject.org; linux-ker...@vger.kernel.org; > step...@networkplumber.org; stefa...@redhat.com; netdev@vger.kernel.org; > a...@canonical.com; pebo...@tiscali.nl; dan.carpen...@oracle.com > Subject: RE: [PATCH V4 7/7] Drivers: hv: vmbus: disable local interrupt when > hvsock's callback is running > > > From: David Miller > > Sent: Thursday, July 30, 2015 6:28 > > > From: Dexuan Cui > > > Date: Tue, 28 Jul 2015 05:35:30 -0700 > > > > > > In the SMP guest case, when the per-channel callback hvsock_events() is > > > running on virtual CPU A, if the guest tries to close the connection on > > > virtual CPU B: we invoke vmbus_close() -> vmbus_close_internal(), > > > then we can have trouble: on B, vmbus_close_internal() will send IPI > > > reset_channel_cb() to A, trying to set channel->onchannel_callbackto NULL; > > > on A, if the IPI handler happens between > > > "if (channel->onchannel_callback != NULL)" and invoking > > > channel->onchannel_callback, we'll invoke a function pointer of NULL. > > > > > > This is why the patch is necessary. > > > > > Sorry, I do not accept that you must use conditional locking and/or > > IRQ disabling. > > > > Boil it down to what is necessary for the least common denominator, > > and use that unconditionally. > > Hi David, > Thanks for the comment! > > I agree with you it's not clean to use conditional IRQ disabling. > > Here I didn't use unconditionally IRQ disabling because the Hyper-V netvsc > and storvsc driver's vmbus event callbacks (i.e. netvsc_channel_cb() and > storvsc_on_channel_callback()) may take relatively long time (e.g., netvsc can > operate at a speed of 10Gb) and I think it's bad to disable IRQ for long time > when the callbacks are running in a tasklet context, e.g., the Hyper-V timer > can be affected: see vmbus_isr() -> hv_process_timer_expiration(). > > To resolve the race condition between vmbus_close_internal() and > process_chn_event() in SMP case, now I propose a new method: > > we can serialize the 2 paths by adding > tasklet_disable(hv_context.event_dpc[channel->target_cpu]) and > tasklet_enable(...) in vmbus_close_internal(). > > In this way, we need the least change and we can drop this patch. > > Please let me know your opinion. > > -- Dexuan Hi David, KY and all, May I know your opinion about my idea of adding tasklet_disable/enbable() in vmbus_close_internal() and dropping this patch? Thanks, -- Dexuan -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v4 2/4] ip_gre: Add support to collect tunnel metadata.
Following patch create new tunnel flag which enable tunnel metadata collection on given device. Signed-off-by: Pravin B Shelar --- include/net/ip_tunnels.h | 7 +- include/uapi/linux/if_tunnel.h | 1 + net/ipv4/ip_gre.c | 195 + net/ipv4/ip_tunnel.c | 37 ++-- net/ipv4/ipip.c| 2 +- net/ipv6/sit.c | 2 +- 6 files changed, 216 insertions(+), 28 deletions(-) diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 4798441..984dbfa 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -82,6 +82,8 @@ struct ip_tunnel_dst { __be32 saddr; }; +struct metadata_dst; + struct ip_tunnel { struct ip_tunnel __rcu *next; struct hlist_node hash_node; @@ -115,6 +117,7 @@ struct ip_tunnel { unsigned intprl_count; /* # of entries in PRL */ int ip_tnl_net_id; struct gro_cellsgro_cells; + boolcollect_md; }; #define TUNNEL_CSUM__cpu_to_be16(0x01) @@ -149,6 +152,7 @@ struct tnl_ptk_info { struct ip_tunnel_net { struct net_device *fb_tunnel_dev; struct hlist_head tunnels[IP_TNL_HASH_SIZE]; + struct ip_tunnel __rcu *collect_md_tun; }; struct ip_tunnel_encap_ops { @@ -235,7 +239,8 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, __be32 key); int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, - const struct tnl_ptk_info *tpi, bool log_ecn_error); + const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst, + bool log_ecn_error); int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[], struct ip_tunnel_parm *p); int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[], diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index bd3cc11..af4de90 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h @@ -112,6 +112,7 @@ enum { IFLA_GRE_ENCAP_FLAGS, IFLA_GRE_ENCAP_SPORT, IFLA_GRE_ENCAP_DPORT, + IFLA_GRE_COLLECT_METADATA, __IFLA_GRE_MAX, }; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5fd7064..554a760 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include #include #include +#include #if IS_ENABLED(CONFIG_IPV6) #include @@ -200,9 +202,29 @@ static int ipgre_err(struct sk_buff *skb, u32 info, return PACKET_RCVD; } +static __be64 key_to_tunnel_id(__be32 key) +{ +#ifdef __BIG_ENDIAN + return (__force __be64)((__force u32)key); +#else + return (__force __be64)((__force u64)key << 32); +#endif +} + +/* Returns the least-significant 32 bits of a __be64. */ +static __be32 tunnel_id_to_key(__be64 x) +{ +#ifdef __BIG_ENDIAN + return (__force __be32)x; +#else + return (__force __be32)((__force u64)x >> 32); +#endif +} + static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) { struct net *net = dev_net(skb->dev); + struct metadata_dst *tun_dst = NULL; struct ip_tunnel_net *itn; const struct iphdr *iph; struct ip_tunnel *tunnel; @@ -218,40 +240,162 @@ static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) if (tunnel) { skb_pop_mac_header(skb); - ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error); + if (tunnel->collect_md) { + struct ip_tunnel_info *info; + + tun_dst = metadata_dst_alloc(0, GFP_ATOMIC); + if (!tun_dst) + return PACKET_REJECT; + + info = &tun_dst->u.tun_info; + info->key.ipv4_src = iph->saddr; + info->key.ipv4_dst = iph->daddr; + info->key.ipv4_tos = iph->tos; + info->key.ipv4_ttl = iph->ttl; + + info->mode = IP_TUNNEL_INFO_RX; + info->key.tun_flags = tpi->flags & + (TUNNEL_CSUM | TUNNEL_KEY); + info->key.tun_id = key_to_tunnel_id(tpi->key); + + info->key.tp_src = 0; + info->key.tp_dst = 0; + } + + ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); return PACKET_RCVD; } return PACKET_REJECT; } +static void build_header(struct sk_buff *skb, int hdr_len, __be16 flags, +__be16 proto, __be32 key, __be32 seq) +{ + struct gre_base_hdr *greh; + + skb_push(skb, hdr_len); + + skb_reset_t
[PATCH net-next v4 4/4] gre: Remove support for sharing GRE protocol hook.
Support for sharing GREPROTO_CISCO port was added so that OVS gre port and kernel GRE devices can co-exist. After flow-based tunneling patches OVS GRE protocol processing is completely moved to ip_gre module. so there is no need for GRE protocol hook. Following patch consolidates GRE protocol related functions into ip_gre module. Signed-off-by: Pravin B Shelar --- include/net/gre.h| 80 ++- net/ipv4/gre_demux.c | 201 +-- net/ipv4/ip_gre.c| 215 +++ 3 files changed, 206 insertions(+), 290 deletions(-) diff --git a/include/net/gre.h b/include/net/gre.h index e3e0845..97eafdc 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -4,6 +4,12 @@ #include #include +struct gre_base_hdr { + __be16 flags; + __be16 protocol; +}; +#define GRE_HEADER_SECTION 4 + #define GREPROTO_CISCO 0 #define GREPROTO_PPTP 1 #define GREPROTO_MAX 2 @@ -14,83 +20,9 @@ struct gre_protocol { void (*err_handler)(struct sk_buff *skb, u32 info); }; -struct gre_base_hdr { - __be16 flags; - __be16 protocol; -}; -#define GRE_HEADER_SECTION 4 - int gre_add_protocol(const struct gre_protocol *proto, u8 version); int gre_del_protocol(const struct gre_protocol *proto, u8 version); -struct gre_cisco_protocol { - int (*handler)(struct sk_buff *skb, const struct tnl_ptk_info *tpi); - int (*err_handler)(struct sk_buff *skb, u32 info, - const struct tnl_ptk_info *tpi); - u8 priority; -}; - -int gre_cisco_register(struct gre_cisco_protocol *proto); -int gre_cisco_unregister(struct gre_cisco_protocol *proto); - struct net_device *gretap_fb_dev_create(struct net *net, const char *name, u8 name_assign_type); - -static inline int ip_gre_calc_hlen(__be16 o_flags) -{ - int addend = 4; - - if (o_flags&TUNNEL_CSUM) - addend += 4; - if (o_flags&TUNNEL_KEY) - addend += 4; - if (o_flags&TUNNEL_SEQ) - addend += 4; - return addend; -} - -static inline __be16 gre_flags_to_tnl_flags(__be16 flags) -{ - __be16 tflags = 0; - - if (flags & GRE_CSUM) - tflags |= TUNNEL_CSUM; - if (flags & GRE_ROUTING) - tflags |= TUNNEL_ROUTING; - if (flags & GRE_KEY) - tflags |= TUNNEL_KEY; - if (flags & GRE_SEQ) - tflags |= TUNNEL_SEQ; - if (flags & GRE_STRICT) - tflags |= TUNNEL_STRICT; - if (flags & GRE_REC) - tflags |= TUNNEL_REC; - if (flags & GRE_VERSION) - tflags |= TUNNEL_VERSION; - - return tflags; -} - -static inline __be16 tnl_flags_to_gre_flags(__be16 tflags) -{ - __be16 flags = 0; - - if (tflags & TUNNEL_CSUM) - flags |= GRE_CSUM; - if (tflags & TUNNEL_ROUTING) - flags |= GRE_ROUTING; - if (tflags & TUNNEL_KEY) - flags |= GRE_KEY; - if (tflags & TUNNEL_SEQ) - flags |= GRE_SEQ; - if (tflags & TUNNEL_STRICT) - flags |= GRE_STRICT; - if (tflags & TUNNEL_REC) - flags |= GRE_REC; - if (tflags & TUNNEL_VERSION) - flags |= GRE_VERSION; - - return flags; -} - #endif diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 77562e0..d9c552a 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c @@ -31,7 +31,6 @@ #include static const struct gre_protocol __rcu *gre_proto[GREPROTO_MAX] __read_mostly; -static struct gre_cisco_protocol __rcu *gre_cisco_proto_list[GRE_IP_PROTO_MAX]; int gre_add_protocol(const struct gre_protocol *proto, u8 version) { @@ -61,163 +60,6 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version) } EXPORT_SYMBOL_GPL(gre_del_protocol); -static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, - bool *csum_err) -{ - const struct gre_base_hdr *greh; - __be32 *options; - int hdr_len; - - if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr - return -EINVAL; - - greh = (struct gre_base_hdr *)skb_transport_header(skb); - if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING))) - return -EINVAL; - - tpi->flags = gre_flags_to_tnl_flags(greh->flags); - hdr_len = ip_gre_calc_hlen(tpi->flags); - - if (!pskb_may_pull(skb, hdr_len)) - return -EINVAL; - - greh = (struct gre_base_hdr *)skb_transport_header(skb); - tpi->proto = greh->protocol; - - options = (__be32 *)(greh + 1); - if (greh->flags & GRE_CSUM) { - if (skb_checksum_simple_validate(skb)) { - *csum_err = true; - return -EINVAL; - } - - skb_checksum_try_convert(skb, IPPROTO_GR
[PATCH net-next v4 1/4] openvswitch: Move tunnel destroy function to oppenvswitch module.
This function will be used in gre and geneve vport implementations. Signed-off-by: Pravin B Shelar --- net/openvswitch/vport-netdev.c | 21 ++--- net/openvswitch/vport-netdev.h | 2 +- net/openvswitch/vport-vxlan.c | 17 + 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index cddb706..4b70aaa 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c @@ -147,7 +147,7 @@ static struct vport *netdev_create(const struct vport_parms *parms) return ovs_netdev_link(vport, parms->name); } -void ovs_vport_free_rcu(struct rcu_head *rcu) +static void vport_netdev_free(struct rcu_head *rcu) { struct vport *vport = container_of(rcu, struct vport, rcu); @@ -155,7 +155,6 @@ void ovs_vport_free_rcu(struct rcu_head *rcu) dev_put(vport->dev); ovs_vport_free(vport); } -EXPORT_SYMBOL_GPL(ovs_vport_free_rcu); void ovs_netdev_detach_dev(struct vport *vport) { @@ -175,9 +174,25 @@ static void netdev_destroy(struct vport *vport) ovs_netdev_detach_dev(vport); rtnl_unlock(); - call_rcu(&vport->rcu, ovs_vport_free_rcu); + call_rcu(&vport->rcu, vport_netdev_free); } +void ovs_netdev_tunnel_destroy(struct vport *vport) +{ + rtnl_lock(); + if (vport->dev->priv_flags & IFF_OVS_DATAPATH) + ovs_netdev_detach_dev(vport); + + /* Early release so we can unregister the device */ + dev_put(vport->dev); + rtnl_delete_link(vport->dev); + vport->dev = NULL; + rtnl_unlock(); + + call_rcu(&vport->rcu, vport_netdev_free); +} +EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy); + static unsigned int packet_length(const struct sk_buff *skb) { unsigned int length = skb->len - ETH_HLEN; diff --git a/net/openvswitch/vport-netdev.h b/net/openvswitch/vport-netdev.h index 8044126..497cc81 100644 --- a/net/openvswitch/vport-netdev.h +++ b/net/openvswitch/vport-netdev.h @@ -29,9 +29,9 @@ struct vport *ovs_netdev_get_vport(struct net_device *dev); struct vport *ovs_netdev_link(struct vport *vport, const char *name); int ovs_netdev_send(struct vport *vport, struct sk_buff *skb); void ovs_netdev_detach_dev(struct vport *); -void ovs_vport_free_rcu(struct rcu_head *); int __init ovs_netdev_init(void); void ovs_netdev_exit(void); +void ovs_netdev_tunnel_destroy(struct vport *vport); #endif /* vport_netdev.h */ diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 5471733..d8d0384 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c @@ -146,21 +146,6 @@ static struct vport *vxlan_create(const struct vport_parms *parms) return ovs_netdev_link(vport, parms->name); } -static void vxlan_destroy(struct vport *vport) -{ - rtnl_lock(); - if (vport->dev->priv_flags & IFF_OVS_DATAPATH) - ovs_netdev_detach_dev(vport); - - /* Early release so we can unregister the device */ - dev_put(vport->dev); - rtnl_delete_link(vport->dev); - vport->dev = NULL; - rtnl_unlock(); - - call_rcu(&vport->rcu, ovs_vport_free_rcu); -} - static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, struct ip_tunnel_info *egress_tun_info) { @@ -183,7 +168,7 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, static struct vport_ops ovs_vxlan_netdev_vport_ops = { .type = OVS_VPORT_TYPE_VXLAN, .create = vxlan_create, - .destroy= vxlan_destroy, + .destroy= ovs_netdev_tunnel_destroy, .get_options= vxlan_get_options, .send = ovs_netdev_send, .get_egress_tun_info= vxlan_get_egress_tun_info, -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next v4 3/4] openvswitch: Use regular GRE net_device instead of vport
Using flow based tunneling, we can implement OVS GRE vport. This patch removes all of the OVS specific GRE code and make OVS use a ip_gre net_device. Minimal GRE vport is kept to handle compatibility with current userspace application. Signed-off-by: Pravin B Shelar --- include/net/gre.h | 12 +-- net/ipv4/gre_demux.c| 34 --- net/ipv4/ip_gre.c | 36 +++ net/openvswitch/Kconfig | 1 - net/openvswitch/vport-gre.c | 237 5 files changed, 60 insertions(+), 260 deletions(-) diff --git a/include/net/gre.h b/include/net/gre.h index b531820..e3e0845 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -33,16 +33,8 @@ struct gre_cisco_protocol { int gre_cisco_register(struct gre_cisco_protocol *proto); int gre_cisco_unregister(struct gre_cisco_protocol *proto); -void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi, - int hdr_len); - -static inline struct sk_buff *gre_handle_offloads(struct sk_buff *skb, - bool csum) -{ - return iptunnel_handle_offloads(skb, csum, - csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); -} - +struct net_device *gretap_fb_dev_create(struct net *net, const char *name, + u8 name_assign_type); static inline int ip_gre_calc_hlen(__be16 o_flags) { diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 4a7b5b2..77562e0 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c @@ -61,40 +61,6 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version) } EXPORT_SYMBOL_GPL(gre_del_protocol); -void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi, - int hdr_len) -{ - struct gre_base_hdr *greh; - - skb_push(skb, hdr_len); - - skb_reset_transport_header(skb); - greh = (struct gre_base_hdr *)skb->data; - greh->flags = tnl_flags_to_gre_flags(tpi->flags); - greh->protocol = tpi->proto; - - if (tpi->flags&(TUNNEL_KEY|TUNNEL_CSUM|TUNNEL_SEQ)) { - __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4); - - if (tpi->flags&TUNNEL_SEQ) { - *ptr = tpi->seq; - ptr--; - } - if (tpi->flags&TUNNEL_KEY) { - *ptr = tpi->key; - ptr--; - } - if (tpi->flags&TUNNEL_CSUM && - !(skb_shinfo(skb)->gso_type & - (SKB_GSO_GRE|SKB_GSO_GRE_CSUM))) { - *ptr = 0; - *(__sum16 *)ptr = csum_fold(skb_checksum(skb, 0, -skb->len, 0)); - } - } -} -EXPORT_SYMBOL_GPL(gre_build_header); - static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, bool *csum_err) { diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 554a760..49d1402 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -318,6 +318,13 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev, ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol); } +static struct sk_buff *gre_handle_offloads(struct sk_buff *skb, + bool csum) +{ + return iptunnel_handle_offloads(skb, csum, + csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); +} + static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) { struct ip_tunnel_info *tun_info; @@ -1012,6 +1019,35 @@ static struct rtnl_link_ops ipgre_tap_ops __read_mostly = { .get_link_net = ip_tunnel_get_link_net, }; +struct net_device *gretap_fb_dev_create(struct net *net, const char *name, + u8 name_assign_type) +{ + struct nlattr *tb[IFLA_MAX + 1]; + struct net_device *dev; + struct ip_tunnel *t; + int err; + + memset(&tb, 0, sizeof(tb)); + + dev = rtnl_create_link(net, name, name_assign_type, + &ipgre_tap_ops, tb); + if (IS_ERR(dev)) + return dev; + + /* Configure flow based GRE device. */ + t = netdev_priv(dev); + t->collect_md = true; + + err = ipgre_newlink(net, dev, tb, NULL); + if (err < 0) + goto out; + return dev; +out: + free_netdev(dev); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(gretap_fb_dev_create); + static int __net_init ipgre_tap_init_net(struct net *net) { return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0"); diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index 1584040..c56f4d4 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig @@ -34,7 +34,6 @@ config OPENVSWITCH config OPENVSWITCH_GRE
[PATCH net-next v4 0/4] GRE: Use flow based tunneling for OVS GRE vport.
Following patches make use of new flow based tunneling API from kernel. This allows us to directly use netdev based GRE tunnel implementation. While doing so I have removed GRE demux API which were targeted for OVS. Most of GRE protocol code is now consolidated in ip_gre module. v3-v4: Added interface to ip-gre device to enable meta data collection. While doing this I split second patch into two patches. v2-v3: Add API to create GRE flow based device. --- Pravin B Shelar (4): openvswitch: Move tunnel destroy function to oppenvswitch module. ip_gre: Add support to collect tunnel metadata. openvswitch: Use regular GRE net_device instead of vport gre: Remove support for sharing GRE protocol hook. include/net/gre.h | 92 + include/net/ip_tunnels.h | 7 +- include/uapi/linux/if_tunnel.h | 1 + net/ipv4/gre_demux.c | 235 +- net/ipv4/ip_gre.c | 446 ++--- net/ipv4/ip_tunnel.c | 37 +++- net/ipv4/ipip.c| 2 +- net/ipv6/sit.c | 2 +- net/openvswitch/Kconfig| 1 - net/openvswitch/vport-gre.c| 237 ++ net/openvswitch/vport-netdev.c | 21 +- net/openvswitch/vport-netdev.h | 2 +- net/openvswitch/vport-vxlan.c | 17 +- 13 files changed, 502 insertions(+), 598 deletions(-) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] [trivial] net:wimax: Fix doucble word "the the" in networking.xml
This patch fix a double word "the the" in Documentation/DocBook/networking.xml and Documentation/DocBook/networking/API-Wimax-report-rfkill-sw.html. These files are generated from comment in source, so I had to fix the typo in net/wimax/io-rfkill.c Signed-off-by: Masanari Iida --- net/wimax/op-rfkill.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c index 7d73054..477364a 100644 --- a/net/wimax/op-rfkill.c +++ b/net/wimax/op-rfkill.c @@ -135,8 +135,7 @@ EXPORT_SYMBOL_GPL(wimax_report_rfkill_hw); * @state: New state of the RF kill switch. %WIMAX_RF_ON radio on, * %WIMAX_RF_OFF radio off. * - * Reports changes in the software RF switch state to the the WiMAX - * stack. + * Reports changes in the software RF switch state to the WiMAX stack. * * The main use is during initialization, so the driver can query the * device for its current software radio kill switch state and feed it -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 3/4] bpf: Implement function bpf_perf_event_read() that get the selected hardware PMU conuter
于 2015/8/5 21:53, Peter Zijlstra 写道: > On Wed, Aug 05, 2015 at 12:04:25PM +0200, Peter Zijlstra wrote: >> Also, you probably want a WARN_ON(in_nmi()) there, this function is >> _NOT_ NMI safe. > > I had a wee think about that, and I think the below is safe. > > (with the obvious problem that WARN from NMI context is not safe) > > It does not give you up-to-date overcommit times but your version didn't > either so I'm assuming you don't need those, if you do need those it > needs more but we can do that too. > > --- > include/linux/perf_event.h | 1 + > kernel/events/core.c | 53 > ++ > 2 files changed, 54 insertions(+) > > diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h > index 2027809433b3..64e821dd64f0 100644 > --- a/include/linux/perf_event.h > +++ b/include/linux/perf_event.h > @@ -659,6 +659,7 @@ perf_event_create_kernel_counter(struct perf_event_attr > *attr, > void *context); > extern void perf_pmu_migrate_context(struct pmu *pmu, > int src_cpu, int dst_cpu); > +extern u64 perf_event_read_local(struct perf_event *event); > extern u64 perf_event_read_value(struct perf_event *event, >u64 *enabled, u64 *running); > > diff --git a/kernel/events/core.c b/kernel/events/core.c > index 39753bfd9520..7105d37763c1 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -3222,6 +3222,59 @@ static inline u64 perf_event_count(struct perf_event > *event) > return __perf_event_count(event); > } > > +/* > + * NMI-safe method to read a local event, that is an event that > + * is: > + * - either for the current task, or for this CPU > + * - does not have inherit set, for inherited task events > + * will not be local and we cannot read them atomically > + * - must not have a pmu::count method > + */ > +u64 perf_event_read_local(struct perf_event *event) > +{ > + unsigned long flags; > + u64 val; > + > + /* > + * Disabling interrupts avoids all counter scheduling (context > + * switches, timer based rotation and IPIs). > + */ > + local_irq_safe(flags); s/local_irq_safe/local_irq_save, and I have compiled and tested this function and it is fine. Will use it in the next set. Thanks. > + > + /* If this is a per-task event, it must be for current */ > + WARN_ON_ONCE((event->attach_state & PERF_ATTACH_TASK) && > + event->hw.target != current); > + > + /* If this is a per-CPU event, it must be for this CPU */ > + WARN_ON_ONCE(!(event->attach_state & PERF_ATTACH_TASK) && > + event->cpu != smp_processor_id()); > + > + /* > + * It must not be an event with inherit set, we cannot read > + * all child counters from atomic context. > + */ > + WARN_ON_ONCE(event->attr.inherit); > + > + /* > + * It must not have a pmu::count method, those are not > + * NMI safe. > + */ > + WARN_ON_ONCE(event->pmu->count); > + > + /* > + * If the event is currently on this CPU, its either a per-task event, > + * or local to this CPU. Furthermore it means its ACTIVE (otherwise > + * oncpu == -1). > + */ > + if (event->oncpu == smp_processor_id()) > + event->pmu->read(event); > + > + val = local64_read(&event->count); > + local_irq_restore(flags); > + > + return val; > +} > + > static u64 perf_event_read(struct perf_event *event) > { > /* > > . > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v5 net-next 4/4] tcp: add NV congestion control
On Wed, Aug 5, 2015 at 3:39 AM, Lawrence Brakmo wrote: > This is a request for comments. Nice to see more development on delay-based congestion control. It would be good to see how NV stacks up against CDG. Any chance of adding cdg as a congestion control parameter to your experiments? Experiments on NV without its temporary cwnd reductions would also be of interest -- to get a reference of how effective this mechanism is. > +#define NV_INIT_RTT 0x Maybe use U32_MAX? > +static void tcpnv_init(struct sock *sk) > +{ > + struct tcpnv *ca = inet_csk_ca(sk); > + > + tcpnv_reset(ca, sk); > + > + ca->nv_min_rtt_reset_jiffies = jiffies + 2*HZ; > + ca->nv_min_rtt = NV_INIT_RTT; > + ca->nv_min_rtt_new = NV_INIT_RTT; > + ca->nv_enable = nv_enable; Can this assignment be ca->nv_enable = 1? That would match the TCP_CA_Open case in tcpnv_state(). > + if (nv_dec_eval_min_calls > 255) > + nv_dec_eval_min_calls = 255; > + if (nv_rtt_min_cnt > 63) > + nv_rtt_min_cnt = 63; nv_dec_eval_min_calls can be clamped to 0-255 by changing its type to u8. nv_rtt_min_cnt can also be u8? In struct tcpnv, perhaps move nv_rtt_cnt to the available byte. > +static void tcpnv_cong_avoid(struct sock *sk, u32 ack, u32 acked) > +{ > + struct tcp_sock *tp = tcp_sk(sk); > + struct tcpnv *ca = inet_csk_ca(sk); > + > + if (!tcp_is_cwnd_limited(sk)) > + return; > + > + /* Only grow cwnd if NV has not detected congestion */ > + if (nv_enable && ca->nv_enable && !ca->nv_allow_cwnd_growth) > + return; The check for ca->nv_enable might be overly harsh on some unfortunate sockets in TCP_CA_Disorder. Is it needed here? > +static void tcpnv_acked(struct sock *sk, struct ack_sample *sample) Maybe move some of this function to tcpnv_cong_avoid()? > +{ > + const struct inet_connection_sock *icsk = inet_csk(sk); > + struct tcp_sock *tp = tcp_sk(sk); > + struct tcpnv *ca = inet_csk_ca(sk); > + unsigned long now = jiffies; > + s64 rate64 = 0; > + u32 rate, max_win, cwnd_by_slope; > + u32 avg_rtt; > + u32 bytes_acked = 0; > + > + /* Some calls are for duplicates without timetamps */ > + if (sample->rtt_us < 0) > + return; > + > + /* If not in TCP_CA_Open state, skip. */ > + if (icsk->icsk_ca_state != TCP_CA_Open) > + return; Consider using samples in other states too, especially TCP_CA_Disorder. Linux 4.2 enhances RTT sampling from SACKs, so any non-negative RTT sample should be fully usable. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [net-next 07/15] i40e/i40evf: Add TX/RX outer UDP checksum support for X722
On Wed, 5 Aug 2015 17:13:21 -0700 Tom Herbert wrote: > On Wed, Aug 5, 2015 at 4:52 PM, Jeff Kirsher > wrote: > > From: Anjali Singhai Jain > > if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE) > > tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; > > + if (vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE) > > + tx_ring->flags |= I40E_TXR_FLAGS_OUTER_UDP_CSUM; > > Just curious... is there a difference between enabling the outer UDP > checksum (of a tunnel) and just enabling checksum offload for UDP > packets? Yes, the hardware knows the difference (or we actually tell it the difference) between a UDP packet and a tunnel inside a UDP packet. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sky2: Add module parameter for passing the MAC address
On 05/08/15 16:16, Stephen Hemminger wrote: > Something like this: > > Subject: [PATCH net-next] sky2: use random address if EEPROM is bad > > On some embedded systems the EEPROM does not contain a valid MAC address. > In that case it is better to fallback to a generated mac address and > let init scripts fix the value later. > > Reported-by: Liviu Dudau > Signed-off-by: Stephen Hemminger > > > --- a/drivers/net/ethernet/marvell/sky2.c 2015-05-21 15:13:03.621126050 > -0700 > +++ b/drivers/net/ethernet/marvell/sky2.c 2015-08-05 16:12:38.734534467 > -0700 > @@ -4819,6 +4819,16 @@ static struct net_device *sky2_init_netd > memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, > ETH_ALEN); > > + /* if the address is invalid, use a random value */ > + if (!is_valid_ether_addr(dev->dev_addr)) { > + struct sockaddr sa = { AF_UNSPEC }; > + > + netdev_warn(dev, > + "Invalid MAC address defaulting to random\n"); > + sky2_set_mac_address(dev, &sa); > + dev->addr_assign_type |= NET_ADDR_RANDOM; There is a helper for that: eth_hw_addr_random() which sets the addr_assign_type for you and copies the address to dev->dev_addr. -- Florian -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: rtnl_mutex deadlock?
On Wed, Aug 05, 2015 at 08:59:07PM +0200, Daniel Borkmann wrote: > > Here's a theory and patch below. Herbert, Thomas, does this make any > sense to you resp. sound plausible? ;) It's certainly possible. Whether it's plausible I'm not so sure. The netlink hashtable is unlimited in size. So it should always be expanding, not rehashing. The bug you found should only affect rehashing. > I'm not quite sure what's best to return from here, i.e. whether we > propagate -ENOMEM or instead retry over and over again hoping that the > rehashing completed (and no new rehashing started in the mean time) ... Please use something other than ENOMEM as it is already heavily used in this context. Perhaps EOVERFLOW? We should probably add a WARN_ON_ONCE in rhashtable_insert_rehash since two concurrent rehashings indicates something is going seriously wrong. Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sky2: Add module parameter for passing the MAC address
From: Liviu Dudau Date: Wed, 5 Aug 2015 16:50:54 +0100 > For designs where EEPROMs are not connected to PCI Yukon2 > chips we need to get the MAC address from the firmware. > Add a module parameter called 'mac_address' for this. It > will be used if no DT node can be found and the B2_MAC > register holds an invalid value. > > Signed-off-by: Liviu Dudau Sorry, such module options are absolutely not allowed. If an invalid MAC is present, it should be set to a random one via eth_random_addr(). -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [net-next 07/15] i40e/i40evf: Add TX/RX outer UDP checksum support for X722
On Wed, Aug 5, 2015 at 4:52 PM, Jeff Kirsher wrote: > From: Anjali Singhai Jain > > X722 supports offloading of outer UDP TX and RX checksum for tunneled > packets. This patch exposes the support and leaves it enabled by > default. > > Signed-off-by: Anjali Singhai Jain > Signed-off-by: Catherine Sullivan > Tested-by: Jim Young > Signed-off-by: Jeff Kirsher > --- > drivers/net/ethernet/intel/i40e/i40e_main.c | 2 ++ > drivers/net/ethernet/intel/i40e/i40e_txrx.c | 16 +++- > drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 ++ > drivers/net/ethernet/intel/i40e/i40e_type.h | 10 -- > drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 13 + > drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 2 ++ > drivers/net/ethernet/intel/i40evf/i40e_type.h | 10 -- > 7 files changed, 50 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c > b/drivers/net/ethernet/intel/i40e/i40e_main.c > index 28f547c..d9cb87f 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_main.c > +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c > @@ -7073,6 +7073,8 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi) > tx_ring->dcb_tc = 0; > if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE) > tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; > + if (vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE) > + tx_ring->flags |= I40E_TXR_FLAGS_OUTER_UDP_CSUM; Just curious... is there a difference between enabling the outer UDP checksum (of a tunnel) and just enabling checksum offload for UDP packets? Tom > vsi->tx_rings[i] = tx_ring; > > rx_ring = &tx_ring[1]; > diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c > b/drivers/net/ethernet/intel/i40e/i40e_txrx.c > index 7d0a5ea..57dc5d2 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c > +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c > @@ -1429,7 +1429,8 @@ static inline void i40e_rx_checksum(struct i40e_vsi > *vsi, > * so the total length of IPv4 header is IHL*4 bytes > * The UDP_0 bit *may* bet set if the *inner* header is UDP > */ > - if (ipv4_tunnel) { > + if (!(vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE) && > + (ipv4_tunnel)) { > skb->transport_header = skb->mac_header + > sizeof(struct ethhdr) + > (ip_hdr(skb)->ihl * 4); > @@ -2301,11 +2302,15 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, > u32 *tx_flags, > struct iphdr *this_ip_hdr; > u32 network_hdr_len; > u8 l4_hdr = 0; > + struct udphdr *oudph; > + struct iphdr *oiph; > u32 l4_tunnel = 0; > > if (skb->encapsulation) { > switch (ip_hdr(skb)->protocol) { > case IPPROTO_UDP: > + oudph = udp_hdr(skb); > + oiph = ip_hdr(skb); > l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING; > *tx_flags |= I40E_TX_FLAGS_VXLAN_TUNNEL; > break; > @@ -2342,6 +2347,15 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, > u32 *tx_flags, > *tx_flags &= ~I40E_TX_FLAGS_IPV4; > *tx_flags |= I40E_TX_FLAGS_IPV6; > } > + if ((tx_ring->flags & I40E_TXR_FLAGS_OUTER_UDP_CSUM) && > + (l4_tunnel == I40E_TXD_CTX_UDP_TUNNELING)&& > + (*cd_tunneling & I40E_TXD_CTX_QW0_EXT_IP_MASK)) { > + oudph->check = ~csum_tcpudp_magic(oiph->saddr, > + oiph->daddr, > + (skb->len - > skb_transport_offset(skb)), > + IPPROTO_UDP, 0); > + *cd_tunneling |= I40E_TXD_CTX_QW0_L4T_CS_MASK; > + } > } else { > network_hdr_len = skb_network_header_len(skb); > this_ip_hdr = ip_hdr(skb); > diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h > b/drivers/net/ethernet/intel/i40e/i40e_txrx.h > index 0e40994..f1385a1 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h > +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h > @@ -267,6 +267,8 @@ struct i40e_ring { > > u16 flags; > #define I40E_TXR_FLAGS_WB_ON_ITR BIT(0) > +#define I40E_TXR_FLAGS_OUTER_UDP_CSUM BIT(1) > + > /* stats structs */ > struct i40e_queue_stats stats; > struct u64_stats_sync syncp; > diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h > b/drivers/net/ethernet/intel/i40e/i40e_type.h > index 1ffd271..b93357d 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_type.h > +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h > @@ -607,14 +607,18 @@ enum i40e_rx_desc_status_bits { > I
[net-next 11/15] e1000e: Fix EEE in Sx implementation
From: Raanan Avargil This patch implements the EEE in Sx code so that it only applies to parts that support EEE in Sx (as opposed to all parts that support EEE). It also uses the existing eee_advert and eee_lp_abiliity to set just the bits (100/1000) that should be set. Signed-off-by: Raanan Avargil Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index fea1601..b32bc48 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6317,6 +6317,33 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) return retval; } + /* Ensure that the appropriate bits are set in LPI_CTRL +* for EEE in Sx +*/ + if ((hw->phy.type >= e1000_phy_i217) && + adapter->eee_advert && hw->dev_spec.ich8lan.eee_lp_ability) { + u16 lpi_ctrl = 0; + + retval = hw->phy.ops.acquire(hw); + if (!retval) { + retval = e1e_rphy_locked(hw, I82579_LPI_CTRL, +&lpi_ctrl); + if (!retval) { + if (adapter->eee_advert & + hw->dev_spec.ich8lan.eee_lp_ability & + I82579_EEE_100_SUPPORTED) + lpi_ctrl |= I82579_LPI_CTRL_100_ENABLE; + if (adapter->eee_advert & + hw->dev_spec.ich8lan.eee_lp_ability & + I82579_EEE_1000_SUPPORTED) + lpi_ctrl |= I82579_LPI_CTRL_1000_ENABLE; + + retval = e1e_wphy_locked(hw, I82579_LPI_CTRL, +lpi_ctrl); + } + } + hw->phy.ops.release(hw); + } /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 03/15] i40e/i40evf: Update FW API with X722 support
From: Anjali Singhai Jain This patch does the firmware API update to support the new X722 device. Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 48 ++ drivers/net/ethernet/intel/i40e/i40e_common.c | 163 + drivers/net/ethernet/intel/i40e/i40e_prototype.h | 11 ++ .../net/ethernet/intel/i40evf/i40e_adminq_cmd.h| 49 ++- drivers/net/ethernet/intel/i40evf/i40e_common.c| 163 + drivers/net/ethernet/intel/i40evf/i40e_prototype.h | 11 ++ 6 files changed, 444 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h index 9101f5c..95d23bf 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h @@ -257,6 +257,10 @@ enum i40e_admin_queue_opc { /* Tunnel commands */ i40e_aqc_opc_add_udp_tunnel = 0x0B00, i40e_aqc_opc_del_udp_tunnel = 0x0B01, + i40e_aqc_opc_set_rss_key= 0x0B02, + i40e_aqc_opc_set_rss_lut= 0x0B03, + i40e_aqc_opc_get_rss_key= 0x0B04, + i40e_aqc_opc_get_rss_lut= 0x0B05, /* Async Events */ i40e_aqc_opc_event_lan_overflow = 0x1001, @@ -821,8 +825,12 @@ struct i40e_aqc_vsi_properties_data { I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT) /* queueing option section */ u8 queueing_opt_flags; +#define I40E_AQ_VSI_QUE_OPT_MULTICAST_UDP_ENA 0x04 +#define I40E_AQ_VSI_QUE_OPT_UNICAST_UDP_ENA0x08 #define I40E_AQ_VSI_QUE_OPT_TCP_ENA0x10 #define I40E_AQ_VSI_QUE_OPT_FCOE_ENA 0x20 +#define I40E_AQ_VSI_QUE_OPT_RSS_LUT_PF 0x00 +#define I40E_AQ_VSI_QUE_OPT_RSS_LUT_VSI0x40 u8 queueing_opt_reserved[3]; /* scheduler section */ u8 up_enable_bits; @@ -2179,6 +2187,46 @@ struct i40e_aqc_del_udp_tunnel_completion { I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion); +struct i40e_aqc_get_set_rss_key { +#define I40E_AQC_SET_RSS_KEY_VSI_VALID (0x1 << 15) +#define I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT 0 +#define I40E_AQC_SET_RSS_KEY_VSI_ID_MASK (0x3FF << \ + I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) + __le16 vsi_id; + u8 reserved[6]; + __le32 addr_high; + __le32 addr_low; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_get_set_rss_key); + +struct i40e_aqc_get_set_rss_key_data { + u8 standard_rss_key[0x28]; + u8 extended_hash_key[0xc]; +}; + +I40E_CHECK_STRUCT_LEN(0x34, i40e_aqc_get_set_rss_key_data); + +struct i40e_aqc_get_set_rss_lut { +#define I40E_AQC_SET_RSS_LUT_VSI_VALID (0x1 << 15) +#define I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT 0 +#define I40E_AQC_SET_RSS_LUT_VSI_ID_MASK (0x3FF << \ + I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) + __le16 vsi_id; +#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT 0 +#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK (0x1 << \ + I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) + +#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI0 +#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF 1 + __le16 flags; + u8 reserved[4]; + __le32 addr_high; + __le32 addr_low; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_get_set_rss_lut); + /* tunnel key structure 0x0B10 */ struct i40e_aqc_tunnel_key_structure { diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 11ec264..114dc64 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -392,6 +392,169 @@ i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw, return status; } +/** + * i40e_aq_get_set_rss_lut + * @hw: pointer to the hardware structure + * @vsi_id: vsi fw index + * @pf_lut: for PF table set true, for VSI table set false + * @lut: pointer to the lut buffer provided by the caller + * @lut_size: size of the lut buffer + * @set: set true to set the table, false to get the table + * + * Internal function to get or set RSS look up table + **/ +static i40e_status i40e_aq_get_set_rss_lut(struct i40e_hw *hw, + u16 vsi_id, bool pf_lut, + u8 *lut, u16 lut_size, + bool set) +{ + i40e_status status; + struct i40e_aq_desc desc; + struct i40e_aqc_get_set_rss_lut *cmd_resp = + (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw; + + if (set) + i40e_fill_default_direct_cmd_desc(&desc, + i40e_aqc_opc_set_rss_lut); + else + i40e_fill_default_direct_cmd_desc(&d
[net-next 09/15] i40e/i40evf: Add ATR HW eviction support for X722
From: Anjali Singhai Jain X722 supports evicting ATR filters in the HW. With this patch, we enable the feature in the driver and avoid filter deletion by the driver. Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 10 ++ drivers/net/ethernet/intel/i40e/i40e_type.h | 4 2 files changed, 14 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 57dc5d2..738aca6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2040,6 +2040,13 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, /* Due to lack of space, no more new filters can be programmed */ if (th->syn && (pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED)) return; + if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) { + /* HW ATR eviction will take care of removing filters on FIN +* and RST packets. +*/ + if (th->fin || th->rst) + return; + } tx_ring->atr_count++; @@ -2095,6 +2102,9 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) & I40E_TXD_FLTR_QW1_CNTINDEX_MASK; + if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) + dtype_cmd |= I40E_TXD_FLTR_QW1_ATR_MASK; + fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype); fdir_desc->rsvd = cpu_to_le32(0); fdir_desc->dtype_cmd_cntindex = cpu_to_le32(dtype_cmd); diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index b93357d..61b6b11 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -1049,6 +1049,10 @@ enum i40e_filter_program_desc_pcmd { #define I40E_TXD_FLTR_QW1_FD_STATUS_MASK (0x3ULL << \ I40E_TXD_FLTR_QW1_FD_STATUS_SHIFT) +#define I40E_TXD_FLTR_QW1_ATR_SHIFT(0xEULL + \ +I40E_TXD_FLTR_QW1_CMD_SHIFT) +#define I40E_TXD_FLTR_QW1_ATR_MASK BIT_ULL(I40E_TXD_FLTR_QW1_ATR_SHIFT) + #define I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT 20 #define I40E_TXD_FLTR_QW1_CNTINDEX_MASK(0x1FFUL << \ I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 05/15] i40e/i40evf: RSS changes for X722
From: Anjali Singhai Jain X722 uses the admin queue to configure RSS. This patch adds the necessary flow changes to configure RSS through AQ. It also adds the separate VMDQ2 lookup tables and hash key programming for X722. X722 also exposes a different set of PCTYPES for RSS, this patch accommodates those changes. Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Signed-off-by: Mitch Williams Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 7 +- drivers/net/ethernet/intel/i40e/i40e_main.c| 156 ++- drivers/net/ethernet/intel/i40e/i40e_txrx.h| 12 ++ drivers/net/ethernet/intel/i40e/i40e_type.h| 15 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 11 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 12 ++ drivers/net/ethernet/intel/i40evf/i40e_type.h | 15 +- drivers/net/ethernet/intel/i40evf/i40evf.h | 2 + drivers/net/ethernet/intel/i40evf/i40evf_main.c| 166 - 9 files changed, 307 insertions(+), 89 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 9914886..66d0780 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -79,10 +79,13 @@ #define I40E_MIN_MSIX 2 #define I40E_DEFAULT_NUM_VMDQ_VSI 8 /* max 256 VSIs */ #define I40E_MIN_VSI_ALLOC51 /* LAN, ATR, FCOE, 32 VF, 16 VMDQ */ -#define I40E_DEFAULT_QUEUES_PER_VMDQ 2 /* max 16 qps */ +/* max 16 qps */ +#define i40e_default_queues_per_vmdq(pf) \ + (((pf)->flags & I40E_FLAG_RSS_AQ_CAPABLE) ? 4 : 1) #define I40E_DEFAULT_QUEUES_PER_VF4 #define I40E_DEFAULT_QUEUES_PER_TC1 /* should be a power of 2 */ -#define I40E_MAX_QUEUES_PER_TC64 /* should be a power of 2 */ +#define i40e_pf_get_max_q_per_tc(pf) \ + (((pf)->flags & I40E_FLAG_128_QP_RSS_CAPABLE) ? 128 : 64) #define I40E_FDIR_RING0 #define I40E_FDIR_RING_COUNT 32 #ifdef I40E_FCOE diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 3269b05..2e84165 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -1550,7 +1550,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, */ qcount = min_t(int, vsi->alloc_queue_pairs, pf->num_lan_msix); num_tc_qps = qcount / numtc; - num_tc_qps = min_t(int, num_tc_qps, I40E_MAX_QUEUES_PER_TC); + num_tc_qps = min_t(int, num_tc_qps, i40e_pf_get_max_q_per_tc(pf)); /* Setup queue offset/count for all TCs for given VSI */ for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { @@ -7469,62 +7469,139 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf) } /** - * i40e_config_rss - Prepare for RSS if used + * i40e_config_rss_aq - Prepare for RSS using AQ commands + * @vsi: vsi structure + * @seed: RSS hash seed + **/ +static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed) +{ + struct i40e_aqc_get_set_rss_key_data rss_key; + struct i40e_pf *pf = vsi->back; + struct i40e_hw *hw = &pf->hw; + bool pf_lut = false; + u8 *rss_lut; + int ret, i; + + memset(&rss_key, 0, sizeof(rss_key)); + memcpy(&rss_key, seed, sizeof(rss_key)); + + rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL); + if (!rss_lut) + return -ENOMEM; + + /* Populate the LUT with max no. of queues in round robin fashion */ + for (i = 0; i < vsi->rss_table_size; i++) + rss_lut[i] = i % vsi->rss_size; + + ret = i40e_aq_set_rss_key(hw, vsi->id, &rss_key); + if (ret) { + dev_info(&pf->pdev->dev, +"Cannot set RSS key, err %s aq_err %s\n", +i40e_stat_str(&pf->hw, ret), +i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); + return ret; + } + + if (vsi->type == I40E_VSI_MAIN) + pf_lut = true; + + ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, rss_lut, + vsi->rss_table_size); + if (ret) + dev_info(&pf->pdev->dev, +"Cannot set RSS lut, err %s aq_err %s\n", +i40e_stat_str(&pf->hw, ret), +i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); + + return ret; +} + +/** + * i40e_vsi_config_rss - Prepare for VSI(VMDq) RSS if used + * @vsi: VSI structure + **/ +static int i40e_vsi_config_rss(struct i40e_vsi *vsi) +{ + u8 seed[I40E_HKEY_ARRAY_SIZE]; + struct i40e_pf *pf = vsi->back; + + netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE); + vsi->rss_size = min_t(int, pf->rss_size, vsi->num_queue_pairs); + + if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) + retur
[net-next 07/15] i40e/i40evf: Add TX/RX outer UDP checksum support for X722
From: Anjali Singhai Jain X722 supports offloading of outer UDP TX and RX checksum for tunneled packets. This patch exposes the support and leaves it enabled by default. Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 ++ drivers/net/ethernet/intel/i40e/i40e_txrx.c | 16 +++- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 ++ drivers/net/ethernet/intel/i40e/i40e_type.h | 10 -- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 13 + drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 2 ++ drivers/net/ethernet/intel/i40evf/i40e_type.h | 10 -- 7 files changed, 50 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 28f547c..d9cb87f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7073,6 +7073,8 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi) tx_ring->dcb_tc = 0; if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE) tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; + if (vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE) + tx_ring->flags |= I40E_TXR_FLAGS_OUTER_UDP_CSUM; vsi->tx_rings[i] = tx_ring; rx_ring = &tx_ring[1]; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 7d0a5ea..57dc5d2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1429,7 +1429,8 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, * so the total length of IPv4 header is IHL*4 bytes * The UDP_0 bit *may* bet set if the *inner* header is UDP */ - if (ipv4_tunnel) { + if (!(vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE) && + (ipv4_tunnel)) { skb->transport_header = skb->mac_header + sizeof(struct ethhdr) + (ip_hdr(skb)->ihl * 4); @@ -2301,11 +2302,15 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags, struct iphdr *this_ip_hdr; u32 network_hdr_len; u8 l4_hdr = 0; + struct udphdr *oudph; + struct iphdr *oiph; u32 l4_tunnel = 0; if (skb->encapsulation) { switch (ip_hdr(skb)->protocol) { case IPPROTO_UDP: + oudph = udp_hdr(skb); + oiph = ip_hdr(skb); l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING; *tx_flags |= I40E_TX_FLAGS_VXLAN_TUNNEL; break; @@ -2342,6 +2347,15 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags, *tx_flags &= ~I40E_TX_FLAGS_IPV4; *tx_flags |= I40E_TX_FLAGS_IPV6; } + if ((tx_ring->flags & I40E_TXR_FLAGS_OUTER_UDP_CSUM) && + (l4_tunnel == I40E_TXD_CTX_UDP_TUNNELING)&& + (*cd_tunneling & I40E_TXD_CTX_QW0_EXT_IP_MASK)) { + oudph->check = ~csum_tcpudp_magic(oiph->saddr, + oiph->daddr, + (skb->len - skb_transport_offset(skb)), + IPPROTO_UDP, 0); + *cd_tunneling |= I40E_TXD_CTX_QW0_L4T_CS_MASK; + } } else { network_hdr_len = skb_network_header_len(skb); this_ip_hdr = ip_hdr(skb); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 0e40994..f1385a1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -267,6 +267,8 @@ struct i40e_ring { u16 flags; #define I40E_TXR_FLAGS_WB_ON_ITR BIT(0) +#define I40E_TXR_FLAGS_OUTER_UDP_CSUM BIT(1) + /* stats structs */ struct i40e_queue_stats stats; struct u64_stats_sync syncp; diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 1ffd271..b93357d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -607,14 +607,18 @@ enum i40e_rx_desc_status_bits { I40E_RX_DESC_STATUS_CRCP_SHIFT = 4, I40E_RX_DESC_STATUS_TSYNINDX_SHIFT = 5, /* 2 BITS */ I40E_RX_DESC_STATUS_TSYNVALID_SHIFT = 7, - I40E_RX_DESC_STATUS_PIF_SHIFT = 8, + /* Note: Bit 8 is reserved in X710 and XL710 */ + I40E_RX_DESC_STATUS_EXT_UDP_0_SHIFT = 8, I40E_RX_DESC_STATUS_UMBCAST_SHIFT = 9, /* 2 BITS */ I40E_RX_DE
[net-next 14/15] e1000e: Fix tight loop implementation of systime read algorithm
From: Raanan Avargil Change the algorithm. Read systimel twice and check for overflow. If there was no overflow, use the first value. If there was an overflow, read systimeh again and use the second systimel value. Signed-off-by: Raanan Avargil Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 31 -- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 24b7269..96a8166 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4280,18 +4280,29 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc) struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter, cc); struct e1000_hw *hw = &adapter->hw; + u32 systimel_1, systimel_2, systimeh; cycle_t systim, systim_next; - /* SYSTIMH latching upon SYSTIML read does not work well. To fix that -* we don't want to allow overflow of SYSTIML and a change to SYSTIMH -* to occur between reads, so if we read a vale close to overflow, we -* wait for overflow to occur and read both registers when its safe. + /* SYSTIMH latching upon SYSTIML read does not work well. +* This means that if SYSTIML overflows after we read it but before +* we read SYSTIMH, the value of SYSTIMH has been incremented and we +* will experience a huge non linear increment in the systime value +* to fix that we test for overflow and if true, we re-read systime. */ - u32 systim_overflow_latch_fix = 0x3FFF; - - do { - systim = (cycle_t)er32(SYSTIML); - } while (systim > systim_overflow_latch_fix); - systim |= (cycle_t)er32(SYSTIMH) << 32; + systimel_1 = er32(SYSTIML); + systimeh = er32(SYSTIMH); + systimel_2 = er32(SYSTIML); + /* Check for overflow. If there was no overflow, use the values */ + if (systimel_1 < systimel_2) { + systim = (cycle_t)systimel_1; + systim |= (cycle_t)systimeh << 32; + } else { + /* There was an overflow, read again SYSTIMH, and use +* systimel_2 +*/ + systimeh = er32(SYSTIMH); + systim = (cycle_t)systimel_2; + systim |= (cycle_t)systimeh << 32; + } if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) { u64 incvalue, time_delta, rem, temp; -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 08/15] i40e: Add IWARP support for X722
From: Anjali Singhai Jain X722 supports IWARP, this patch handles checking for PE critical errors. Since the driver doesn't support the IWARP interface for now, this patch just does bare minimum to log a message oif a PE critical error happens. Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index d9cb87f..3bb832a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2908,6 +2908,9 @@ static void i40e_enable_misc_int_causes(struct i40e_pf *pf) I40E_PFINT_ICR0_ENA_VFLR_MASK | I40E_PFINT_ICR0_ENA_ADMINQ_MASK; + if (pf->flags & I40E_FLAG_IWARP_ENABLED) + val |= I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK; + if (pf->flags & I40E_FLAG_PTP) val |= I40E_PFINT_ICR0_ENA_TIMESYNC_MASK; @@ -3198,6 +3201,13 @@ static irqreturn_t i40e_intr(int irq, void *data) (icr0 & I40E_PFINT_ICR0_SWINT_MASK)) pf->sw_int_count++; + if ((pf->flags & I40E_FLAG_IWARP_ENABLED) && + (ena_mask & I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK)) { + ena_mask &= ~I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK; + icr0 &= ~I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK; + dev_info(&pf->pdev->dev, "cleared PE_CRITERR\n"); + } + /* only q0 is used in MSI/Legacy mode, and none are used in MSIX */ if (icr0 & I40E_PFINT_ICR0_QUEUE_0_MASK) { -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 15/15] e1000e: Increase driver version number
From: Raanan Avargil Signed-off-by: Raanan Avargil Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 96a8166..546b5da 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -48,7 +48,7 @@ #define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "3.2.5" DRV_EXTRAVERSION +#define DRV_VERSION "3.2.6" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 13/15] e1000e: Fix incorrect ASPM locking
From: Raanan Avargil This patch fixes wrong locking usage. In the context of slot reset, we should use lock. And during resume, there is no need of lock. Reported-by: Bjorn Helgaas Signed-off-by: Raanan Avargil Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index b32bc48..24b7269 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -6493,7 +6493,7 @@ static int __e1000_resume(struct pci_dev *pdev) if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) aspm_disable_flag |= PCIE_LINK_STATE_L1; if (aspm_disable_flag) - e1000e_disable_aspm_locked(pdev, aspm_disable_flag); + e1000e_disable_aspm(pdev, aspm_disable_flag); pci_set_master(pdev); @@ -6771,7 +6771,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) aspm_disable_flag |= PCIE_LINK_STATE_L1; if (aspm_disable_flag) - e1000e_disable_aspm(pdev, aspm_disable_flag); + e1000e_disable_aspm_locked(pdev, aspm_disable_flag); err = pci_enable_device_mem(pdev); if (err) { -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 02/15] i40e/i40evf: Add flags for X722 capabilities
From: Anjali Singhai Jain Add capabilities flags specific to X722. Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 7 +++ drivers/net/ethernet/intel/i40e/i40e_main.c | 8 drivers/net/ethernet/intel/i40evf/i40evf.h | 7 ++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 281fd84..9914886 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -298,6 +298,7 @@ struct i40e_pf { #define I40E_FLAG_VMDQ_ENABLED BIT_ULL(7) #define I40E_FLAG_FDIR_REQUIRES_REINIT BIT_ULL(8) #define I40E_FLAG_NEED_LINK_UPDATE BIT_ULL(9) +#define I40E_FLAG_IWARP_ENABLEDBIT_ULL(10) #ifdef I40E_FCOE #define I40E_FLAG_FCOE_ENABLED BIT_ULL(11) #endif /* I40E_FCOE */ @@ -318,6 +319,12 @@ struct i40e_pf { #endif #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) +#define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) +#define I40E_FLAG_HW_ATR_EVICT_CAPABLE BIT_ULL(32) +#define I40E_FLAG_OUTER_UDP_CSUM_CAPABLE BIT_ULL(33) +#define I40E_FLAG_128_QP_RSS_CAPABLE BIT_ULL(34) +#define I40E_FLAG_WB_ON_ITR_CAPABLEBIT_ULL(35) +#define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE BIT_ULL(38) #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) /* tracks features that get auto disabled by errors */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 9c96706..3269b05 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7785,6 +7785,14 @@ static int i40e_sw_init(struct i40e_pf *pf) I40E_MAX_VF_COUNT); } #endif /* CONFIG_PCI_IOV */ + if (pf->hw.mac.type == I40E_MAC_X722) { + pf->flags |= I40E_FLAG_RSS_AQ_CAPABLE | +I40E_FLAG_128_QP_RSS_CAPABLE | +I40E_FLAG_HW_ATR_EVICT_CAPABLE | +I40E_FLAG_OUTER_UDP_CSUM_CAPABLE | +I40E_FLAG_WB_ON_ITR_CAPABLE | +I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE; + } pf->eeprom_version = 0xDEAD; pf->lan_veb = I40E_NO_VEB; pf->lan_vsi = I40E_NO_VSI; diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index c33c7cc..bd227b3 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h @@ -218,11 +218,15 @@ struct i40evf_adapter { #define I40EVF_FLAG_PF_COMMS_FAILED BIT(8) #define I40EVF_FLAG_RESET_PENDINGBIT(9) #define I40EVF_FLAG_RESET_NEEDED BIT(10) -/* duplcates for common code */ +#define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(11) +#define I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE BIT(12) +/* duplicates for common code */ #define I40E_FLAG_FDIR_ATR_ENABLED 0 #define I40E_FLAG_DCB_ENABLED 0 #define I40E_FLAG_IN_NETPOLLI40EVF_FLAG_IN_NETPOLL #define I40E_FLAG_RX_CSUM_ENABLEDI40EVF_FLAG_RX_CSUM_ENABLED +#define I40E_FLAG_WB_ON_ITR_CAPABLEI40EVF_FLAG_WB_ON_ITR_CAPABLE +#define I40E_FLAG_OUTER_UDP_CSUM_CAPABLE I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE /* flags for admin queue service task */ u32 aq_required; #define I40EVF_FLAG_AQ_ENABLE_QUEUES BIT(0) @@ -234,6 +238,7 @@ struct i40evf_adapter { #define I40EVF_FLAG_AQ_CONFIGURE_QUEUESBIT(6) #define I40EVF_FLAG_AQ_MAP_VECTORS BIT(7) #define I40EVF_FLAG_AQ_HANDLE_RESETBIT(8) +#define I40EVF_FLAG_AQ_CONFIGURE_RSS BIT(9) #define I40EVF_FLAG_AQ_GET_CONFIG BIT(10) /* OS defined structs */ -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 10/15] i40e: Add AQ commands for NVM Update for X722
From: Shannon Nelson X722 does NVM update via the adminq queue, so we need to add support for that. Signed-off-by: Shannon Nelson Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 129 + 1 file changed, 129 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c index ce986af..9b83abc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c @@ -212,6 +212,74 @@ read_nvm_exit: } /** + * i40e_read_nvm_aq - Read Shadow RAM. + * @hw: pointer to the HW structure. + * @module_pointer: module pointer location in words from the NVM beginning + * @offset: offset in words from module start + * @words: number of words to write + * @data: buffer with words to write to the Shadow RAM + * @last_command: tells the AdminQ that this is the last command + * + * Writes a 16 bit words buffer to the Shadow RAM using the admin command. + **/ +static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer, + u32 offset, u16 words, void *data, + bool last_command) +{ + i40e_status ret_code = I40E_ERR_NVM; + struct i40e_asq_cmd_details cmd_details; + + memset(&cmd_details, 0, sizeof(cmd_details)); + + /* Here we are checking the SR limit only for the flat memory model. +* We cannot do it for the module-based model, as we did not acquire +* the NVM resource yet (we cannot get the module pointer value). +* Firmware will check the module-based model. +*/ + if ((offset + words) > hw->nvm.sr_size) + i40e_debug(hw, I40E_DEBUG_NVM, + "NVM write error: offset %d beyond Shadow RAM limit %d\n", + (offset + words), hw->nvm.sr_size); + else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) + /* We can write only up to 4KB (one sector), in one AQ write */ + i40e_debug(hw, I40E_DEBUG_NVM, + "NVM write fail error: tried to write %d words, limit is %d.\n", + words, I40E_SR_SECTOR_SIZE_IN_WORDS); + else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) +!= (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) + /* A single write cannot spread over two sectors */ + i40e_debug(hw, I40E_DEBUG_NVM, + "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n", + offset, words); + else + ret_code = i40e_aq_read_nvm(hw, module_pointer, + 2 * offset, /*bytes*/ + 2 * words, /*bytes*/ + data, last_command, &cmd_details); + + return ret_code; +} + +/** + * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM word to read (0x00 - 0x001FFF) + * @data: word read from the Shadow RAM + * + * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. + **/ +static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, +u16 *data) +{ + i40e_status ret_code = I40E_ERR_TIMEOUT; + + ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, true); + *data = le16_to_cpu(*(__le16 *)data); + + return ret_code; +} + +/** * i40e_read_nvm_word - Reads Shadow RAM * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x00 - 0x001FFF) @@ -222,6 +290,8 @@ read_nvm_exit: i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, u16 *data) { + if (hw->mac.type == I40E_MAC_X722) + return i40e_read_nvm_word_aq(hw, offset, data); return i40e_read_nvm_word_srctl(hw, offset, data); } @@ -257,6 +327,63 @@ static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, } /** + * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ + * @hw: pointer to the HW structure + * @offset: offset of the Shadow RAM word to read (0x00 - 0x001FFF). + * @words: (in) number of words to read; (out) number of words actually read + * @data: words read from the Shadow RAM + * + * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq() + * method. The buffer read is preceded by the NVM ownership take + * and followed by the release. + **/ +static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset, + u16 *words, u16 *data) +{ + i40e_status ret_code; + u16 read_size = *words; + bool last_cmd = false; + u16 words_read = 0; + u16 i = 0
[net-next 12/15] e1000e: Cosmetic changes
From: Raanan Avargil 1) Replace spaces with tab. 2) Move ich8lan related define to the proper context. Signed-off-by: Raanan Avargil Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.h | 4 ++-- drivers/net/ethernet/intel/e1000e/regs.h| 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h index 2645985..34c551e 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h @@ -106,14 +106,14 @@ #define E1000_FEXTNVM11_DISABLE_MULR_FIX 0x2000 /* bit24: RXDCTL thresholds granularity: 0 - cache lines, 1 - descriptors */ -#define E1000_RXDCTL_THRESH_UNIT_DESC 0x0100 +#define E1000_RXDCTL_THRESH_UNIT_DESC 0x0100 #define K1_ENTRY_LATENCY 0 #define K1_MIN_TIME1 #define NVM_SIZE_MULTIPLIER 4096 /*multiplier for NVMS field */ #define E1000_FLASH_BASE_ADDR 0xE000 /*offset of NVM access regs */ #define E1000_CTRL_EXT_NVMVS 0x3 /*NVM valid sector */ - +#define E1000_TARC0_CB_MULTIQ_3_REQ(1 << 28 | 1 << 29) #define PCIE_ICH8_SNOOP_ALLPCIE_NO_SNOOP_ALL #define E1000_ICH_RAR_ENTRIES 7 diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h index b24e5fe..1d5e0b7 100644 --- a/drivers/net/ethernet/intel/e1000e/regs.h +++ b/drivers/net/ethernet/intel/e1000e/regs.h @@ -38,8 +38,8 @@ #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ #define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */ #define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */ -#define E1000_FEXTNVM9 0x5BB4 /* Future Extended NVM 9 - RW */ -#define E1000_FEXTNVM110x5BBC /* Future Extended NVM 11 - RW */ +#define E1000_FEXTNVM9 0x5BB4 /* Future Extended NVM 9 - RW */ +#define E1000_FEXTNVM110x5BBC /* Future Extended NVM 11 - RW */ #define E1000_PCIEANACFG 0x00F18 /* PCIE Analog Config */ #define E1000_FCT 0x00030 /* Flow Control Type - RW */ #define E1000_VET 0x00038 /* VLAN Ether Type - RW */ @@ -125,7 +125,6 @@ (0x054E4 + ((_i - 16) * 8))) #define E1000_SHRAL(_i)(0x05438 + ((_i) * 8)) #define E1000_SHRAH(_i)(0x0543C + ((_i) * 8)) -#define E1000_TARC0_CB_MULTIQ_3_REQ(1 << 28 | 1 << 29) #define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */ #define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */ #define E1000_TDFHS0x03420 /* Tx Data FIFO Head Saved - RW */ -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[net-next 06/15] i40e/i40evf: Add support for writeback on ITR feature for X722
From: Anjali Singhai Jain X722 fixes an issue from X710 where TX descriptor WB would not happen if the interrupts were disabled. In order for the write backs to happen a bit needs to be set in the dynamic interrupt control register called WB_ON_ITR. With this feature, the SW driver need not arm SW interrupts to work around the issue in X710. Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h| 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 2 ++ drivers/net/ethernet/intel/i40e/i40e_txrx.c | 46 +-- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 ++ drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 38 -- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 2 ++ drivers/net/ethernet/intel/i40evf/i40evf.h| 1 + 7 files changed, 74 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 66d0780..0f97883 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -560,6 +560,7 @@ struct i40e_q_vector { cpumask_t affinity_mask; struct rcu_head rcu;/* to avoid race with update stats on free */ char name[I40E_INT_NAME_STR_LEN]; + bool arm_wb_state; } cacheline_internodealigned_in_smp; /* lan device */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 2e84165..28f547c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7071,6 +7071,8 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi) tx_ring->count = vsi->num_desc; tx_ring->size = 0; tx_ring->dcb_tc = 0; + if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE) + tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; vsi->tx_rings[i] = tx_ring; rx_ring = &tx_ring[1]; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 330e4ef..7d0a5ea 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -853,15 +853,40 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) **/ static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector) { - u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK | - I40E_PFINT_DYN_CTLN_ITR_INDX_MASK | /* set noitr */ - I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK | - I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK; - /* allow 00 to be written to the index */ - - wr32(&vsi->back->hw, -I40E_PFINT_DYN_CTLN(q_vector->v_idx + vsi->base_vector - 1), -val); + u16 flags = q_vector->tx.ring[0].flags; + + if (flags & I40E_TXR_FLAGS_WB_ON_ITR) { + u32 val; + + if (q_vector->arm_wb_state) + return; + + val = I40E_PFINT_DYN_CTLN_WB_ON_ITR_MASK; + + wr32(&vsi->back->hw, +I40E_PFINT_DYN_CTLN(q_vector->v_idx + +vsi->base_vector - 1), +val); + q_vector->arm_wb_state = true; + } else if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) { + u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK | + I40E_PFINT_DYN_CTLN_ITR_INDX_MASK | /* set noitr */ + I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK | + I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK; + /* allow 00 to be written to the index */ + + wr32(&vsi->back->hw, +I40E_PFINT_DYN_CTLN(q_vector->v_idx + +vsi->base_vector - 1), val); + } else { + u32 val = I40E_PFINT_DYN_CTL0_INTENA_MASK | + I40E_PFINT_DYN_CTL0_ITR_INDX_MASK | /* set noitr */ + I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK | + I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK; + /* allow 00 to be written to the index */ + + wr32(&vsi->back->hw, I40E_PFINT_DYN_CTL0, val); + } } /** @@ -1918,6 +1943,9 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) return budget; } + if (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR) + q_vector->arm_wb_state = false; + /* Work is done so exit the polling mode and re-enable the interrupt */ napi_complete(napi); if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 8b618d0..0e40994 100644 --- a/drivers/net/ethernet/
[net-next 01/15] i40e/i40evf: Add device ids for X722
From: Anjali Singhai Jain Adding device ids for new hardware X722 Signed-off-by: Anjali Singhai Jain Signed-off-by: Catherine Sullivan Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 10 ++ drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ drivers/net/ethernet/intel/i40e/i40e_type.h | 10 +- drivers/net/ethernet/intel/i40evf/i40e_common.c | 9 + drivers/net/ethernet/intel/i40evf/i40e_type.h | 10 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 1 + 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 167ca0d..11ec264 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -54,6 +54,15 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_20G_KR2: hw->mac.type = I40E_MAC_XL710; break; + case I40E_DEV_ID_SFP_X722: + case I40E_DEV_ID_1G_BASE_T_X722: + case I40E_DEV_ID_10G_BASE_T_X722: + hw->mac.type = I40E_MAC_X722; + break; + case I40E_DEV_ID_X722_VF: + case I40E_DEV_ID_X722_VF_HV: + hw->mac.type = I40E_MAC_X722_VF; + break; case I40E_DEV_ID_VF: case I40E_DEV_ID_VF_HV: hw->mac.type = I40E_MAC_VF; @@ -769,6 +778,7 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw) switch (hw->mac.type) { case I40E_MAC_XL710: + case I40E_MAC_X722: break; default: return I40E_ERR_DEVICE_NOT_SUPPORTED; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 857d294..9c96706 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -76,6 +76,9 @@ static const struct pci_device_id i40e_pci_tbl[] = { {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_C), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2), 0}, + {PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_X722), 0}, + {PCI_VDEVICE(INTEL, I40E_DEV_ID_1G_BASE_T_X722), 0}, + {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T_X722), 0}, /* required last entry */ {0, } }; diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index a20128b..778266f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -47,6 +47,11 @@ #define I40E_DEV_ID_20G_KR20x1587 #define I40E_DEV_ID_VF 0x154C #define I40E_DEV_ID_VF_HV 0x1571 +#define I40E_DEV_ID_SFP_X722 0x37D0 +#define I40E_DEV_ID_1G_BASE_T_X722 0x37D1 +#define I40E_DEV_ID_10G_BASE_T_X7220x37D2 +#define I40E_DEV_ID_X722_VF0x37CD +#define I40E_DEV_ID_X722_VF_HV 0x37D9 #define i40e_is_40G_device(d) ((d) == I40E_DEV_ID_QSFP_A || \ (d) == I40E_DEV_ID_QSFP_B || \ @@ -120,6 +125,8 @@ enum i40e_mac_type { I40E_MAC_X710, I40E_MAC_XL710, I40E_MAC_VF, + I40E_MAC_X722, + I40E_MAC_X722_VF, I40E_MAC_GENERIC, }; @@ -502,7 +509,8 @@ struct i40e_hw { static inline bool i40e_is_vf(struct i40e_hw *hw) { - return hw->mac.type == I40E_MAC_VF; + return (hw->mac.type == I40E_MAC_VF || + hw->mac.type == I40E_MAC_X722_VF); } struct i40e_driver_version { diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c index 56c7e75..eb54e8d 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_common.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c @@ -54,6 +54,15 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_20G_KR2: hw->mac.type = I40E_MAC_XL710; break; + case I40E_DEV_ID_SFP_X722: + case I40E_DEV_ID_1G_BASE_T_X722: + case I40E_DEV_ID_10G_BASE_T_X722: + hw->mac.type = I40E_MAC_X722; + break; + case I40E_DEV_ID_X722_VF: + case I40E_DEV_ID_X722_VF_HV: + hw->mac.type = I40E_MAC_X722_VF; + break; case I40E_DEV_ID_VF: case I40E_DEV_ID_VF_HV: hw->mac.type = I40E_MAC_VF; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h index 4ba9a01..c50536b 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_type.h +++ b/drivers/net/ethernet/intel/i40evf
[net-next 00/15][pull request] Intel Wired LAN Driver Updates 2015-08-05
This series contains updates to i40e, i40evf and e1000e. Anjali adds support for x772 devices to i40e and i40evf. With the added support, x772 supports offloading of the outer UDP transmit and receive checksum for tunneled packets. Also supports evicting ATR filters in the hardware, so update the driver with this new feature set. Raanan provides several fixes for e1000e, first rectifies the Energy Efficient Ethernet in Sx code so that it only applies to parts that actually support EEE in Sx. Fix whitespace and moved ICH8 related define to the proper context. Fixed the ASPM locking which was reported by Bjorn Helgaas. Fix a workaround implementation for systime which could experience a large non-linear increment of the systime value when checking for overflow. The following are changes since commit 9dc20a649609c95ce7c5ac4282656ba627b67d49: Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next and are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue master Anjali Singhai Jain (9): i40e/i40evf: Add device ids for X722 i40e/i40evf: Add flags for X722 capabilities i40e/i40evf: Update FW API with X722 support i40e/i40evf: Update register.h file for X722 i40e/i40evf: RSS changes for X722 i40e/i40evf: Add support for writeback on ITR feature for X722 i40e/i40evf: Add TX/RX outer UDP checksum support for X722 i40e: Add IWARP support for X722 i40e/i40evf: Add ATR HW eviction support for X722 Raanan Avargil (5): e1000e: Fix EEE in Sx implementation e1000e: Cosmetic changes e1000e: Fix incorrect ASPM locking e1000e: Fix tight loop implementation of systime read algorithm e1000e: Increase driver version number Shannon Nelson (1): i40e: Add AQ commands for NVM Update for X722 drivers/net/ethernet/intel/e1000e/ich8lan.h|4 +- drivers/net/ethernet/intel/e1000e/netdev.c | 64 +- drivers/net/ethernet/intel/e1000e/regs.h |5 +- drivers/net/ethernet/intel/i40e/i40e.h | 15 +- drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 48 + drivers/net/ethernet/intel/i40e/i40e_common.c | 173 ++ drivers/net/ethernet/intel/i40e/i40e_main.c| 181 +- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 129 ++ drivers/net/ethernet/intel/i40e/i40e_prototype.h | 11 + drivers/net/ethernet/intel/i40e/i40e_register.h| 1931 +++- drivers/net/ethernet/intel/i40e/i40e_txrx.c| 72 +- drivers/net/ethernet/intel/i40e/i40e_txrx.h| 16 + drivers/net/ethernet/intel/i40e/i40e_type.h| 39 +- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 11 +- .../net/ethernet/intel/i40evf/i40e_adminq_cmd.h| 49 +- drivers/net/ethernet/intel/i40evf/i40e_common.c| 172 ++ drivers/net/ethernet/intel/i40evf/i40e_prototype.h | 11 + drivers/net/ethernet/intel/i40evf/i40e_register.h | 62 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 51 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 16 + drivers/net/ethernet/intel/i40evf/i40e_type.h | 35 +- drivers/net/ethernet/intel/i40evf/i40evf.h | 10 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c| 167 +- 23 files changed, 3136 insertions(+), 136 deletions(-) -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sky2: Add module parameter for passing the MAC address
Something like this: Subject: [PATCH net-next] sky2: use random address if EEPROM is bad On some embedded systems the EEPROM does not contain a valid MAC address. In that case it is better to fallback to a generated mac address and let init scripts fix the value later. Reported-by: Liviu Dudau Signed-off-by: Stephen Hemminger --- a/drivers/net/ethernet/marvell/sky2.c 2015-05-21 15:13:03.621126050 -0700 +++ b/drivers/net/ethernet/marvell/sky2.c 2015-08-05 16:12:38.734534467 -0700 @@ -4819,6 +4819,16 @@ static struct net_device *sky2_init_netd memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); + /* if the address is invalid, use a random value */ + if (!is_valid_ether_addr(dev->dev_addr)) { + struct sockaddr sa = { AF_UNSPEC }; + + netdev_warn(dev, +"Invalid MAC address defaulting to random\n"); + sky2_set_mac_address(dev, &sa); + dev->addr_assign_type |= NET_ADDR_RANDOM; + } + return dev; } -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2 net-next 5/9] openvswitch: Add conntrack action
On Tue, Aug 4, 2015 at 9:49 PM, Joe Stringer wrote: > Expose the kernel connection tracker via OVS. Userspace components can > make use of the "ct()" action, followed by "recirculate", to populate > the conntracking state in the OVS flow key, and subsequently match on > that state. > > Example ODP flows allowing traffic from 1->2, only replies from 2->1: > in_port=1,tcp,action=ct(commit,zone=1),2 > in_port=2,ct_state=-trk,tcp,action=ct(zone=1),recirc(1) > recirc_id=1,in_port=2,ct_state=+trk+est-new,tcp,action=1 > > IP fragments are handled by transparently assembling them as part of the > ct action. The maximum received unit (MRU) size is tracked so that > refragmentation can occur during output. > > IP frag handling contributed by Andy Zhou. > > Signed-off-by: Joe Stringer > Signed-off-by: Justin Pettit > Signed-off-by: Andy Zhou > --- > This can be tested with the corresponding userspace component here: > https://www.github.com/justinpettit/openvswitch conntrack > > v2: Don't take references to devs or dsts in output path. > Shift ovs_ct_init()/ovs_ct_exit() into this patch > Handle output case where flow key is invalidated > Store the entire L2 header to apply to fragments > Various minor simplifications > Improve comments/logs > Style fixes > Rebase > --- > include/uapi/linux/openvswitch.h | 41 > net/openvswitch/Kconfig | 11 + > net/openvswitch/Makefile | 2 + > net/openvswitch/actions.c| 154 - > net/openvswitch/conntrack.c | 475 > +++ > net/openvswitch/conntrack.h | 97 > net/openvswitch/datapath.c | 73 -- > net/openvswitch/datapath.h | 8 + > net/openvswitch/flow.c | 3 + > net/openvswitch/flow.h | 6 + > net/openvswitch/flow_netlink.c | 72 -- > net/openvswitch/flow_netlink.h | 4 +- > net/openvswitch/vport.c | 1 + > 13 files changed, 910 insertions(+), 37 deletions(-) > create mode 100644 net/openvswitch/conntrack.c > create mode 100644 net/openvswitch/conntrack.h > I got sparse warning: net/openvswitch/actions.c:634:1: warning: symbol 'ovs_dst_get_mtu' was not declared. Should it be static? net/openvswitch/actions.c:703:17: warning: cast from restricted __be16 net/openvswitch/actions.c:703:17: warning: incorrect type in argument 1 (different base types) net/openvswitch/actions.c:703:17:expected unsigned short [unsigned] [usertype] val net/openvswitch/actions.c:703:17:got restricted __be16 [usertype] ethertype net/openvswitch/actions.c:703:17: warning: cast from restricted __be16 net/openvswitch/actions.c:703:17: warning: cast from restricted __be16 > -static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port) > +static int ovs_vport_output(struct sock *sock, struct sk_buff *skb) > +{ > + struct ovs_frag_data *data = this_cpu_ptr(&ovs_frag_data_storage); > + struct vport *vport = data->vport; > + > + if (skb_cow_head(skb, data->l2_len) < 0) > + return -ENOMEM; > + Need to free skb here. > + skb->_skb_refdst = data->dst; I think we need to clone dst if there are multiple fragments. Can you test this code with vxlan flow based tunnels? > + *OVS_CB(skb) = data->cb; > + > + /* Reconstruct the MAC header. */ > + skb_push(skb, data->l2_len); > + memcpy(skb->data, &data->l2_data, data->l2_len); > + skb_reset_mac_header(skb); > + skb->protocol = eth_hdr(skb)->h_proto; why do we need to restore skb->protocol? > + skb->vlan_tci = 0; > + Why is vlan_tci set to zero. > + ovs_vport_send(vport, skb); > + return 0; > +} > + > +unsigned int > +ovs_dst_get_mtu(const struct dst_entry *dst) > +{ > + return dst->dev->mtu; > +} > + ... > +static void ovs_fragment(struct vport *vport, struct sk_buff *skb, > +unsigned int mru, __be16 ethertype) > +{ > + if (skb_network_offset(skb) > MAX_L2_LEN) { > + OVS_NLERR(1, "L2 header too long to fragment"); > + return; > + } > + > + if (ethertype == htons(ETH_P_IP)) { > + struct dst_entry ovs_dst; > + > + prepare_frag(vport, skb); > + dst_init(&ovs_dst, &ovs_dst_ops, NULL, 1, > +DST_OBSOLETE_NONE, DST_NOCOUNT); > + ovs_dst.dev = vport->dev; > + > + skb_dst_set_noref(skb, &ovs_dst); > + IPCB(skb)->frag_max_size = mru; > + > + ip_do_fragment(skb->sk, skb, ovs_vport_output); > + } else if (ethertype == htons(ETH_P_IPV6)) { > + const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops(); > + struct rt6_info ovs_rt; > + > + if (!v6ops) { > + kfree_skb(skb); > + return; > + } > + > + prepare_frag(vport, skb); > + memset(&ovs_rt, 0,
Re: [PATCHv2 net-next 2/9] openvswitch: Move MASKED* macros to datapath.h
On Tue, Aug 4, 2015 at 9:49 PM, Joe Stringer wrote: > This will allow the ovs-conntrack code to reuse these macros. > > Signed-off-by: Joe Stringer > Acked-by: Thomas Graf Acked-by: Pravin B Shelar -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2 net-next 1/9] openvswitch: Serialize acts with original netlink len
On Tue, Aug 4, 2015 at 9:49 PM, Joe Stringer wrote: > Previously, we used the kernel-internal netlink actions length to > calculate the size of messages to serialize back to userspace. > However,the sw_flow_actions may not be formatted exactly the same as the > actions on the wire, so store the original actions length when > de-serializing and re-use the original length when serializing. > > Signed-off-by: Joe Stringer > Acked-by: Thomas Graf > --- > net/openvswitch/datapath.c | 2 +- > net/openvswitch/flow.h | 1 + > net/openvswitch/flow_netlink.c | 1 + > 3 files changed, 3 insertions(+), 1 deletion(-) > > diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c > index ffe984f..d5b5473 100644 > --- a/net/openvswitch/datapath.c > +++ b/net/openvswitch/datapath.c > @@ -713,7 +713,7 @@ static size_t ovs_flow_cmd_msg_size(const struct > sw_flow_actions *acts, > > /* OVS_FLOW_ATTR_ACTIONS */ > if (should_fill_actions(ufid_flags)) > - len += nla_total_size(acts->actions_len); > + len += nla_total_size(acts->orig_len); > > return len > + nla_total_size(sizeof(struct ovs_flow_stats)) /* > OVS_FLOW_ATTR_STATS */ > diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h > index b62cdb3..082a87b 100644 > --- a/net/openvswitch/flow.h > +++ b/net/openvswitch/flow.h > @@ -144,6 +144,7 @@ struct sw_flow_id { > > struct sw_flow_actions { > struct rcu_head rcu; > + size_t orig_len;/* From flow_cmd_new netlink actions size */ > u32 actions_len; > struct nlattr actions[]; > }; > diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c > index a6eb77a..d536fb7 100644 > --- a/net/openvswitch/flow_netlink.c > +++ b/net/openvswitch/flow_netlink.c > @@ -1545,6 +1545,7 @@ static struct sw_flow_actions > *nla_alloc_flow_actions(int size, bool log) > return ERR_PTR(-ENOMEM); > > sfa->actions_len = 0; > + sfa->orig_len = size; This is getting updated every time datapath action buffer is expanded (ref: reserve_sfa_size()). So it does not keep original userspace action length. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2 net-next 3/9] ipv6: Export nf_ct_frag6_gather()
On Tue, Aug 4, 2015 at 9:49 PM, Joe Stringer wrote: > Signed-off-by: Joe Stringer > Acked-by: Thomas Graf > --- Acked-by: Pravin B Shelar -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next 1/1] lan78xx: Fix Smatch warnings
Fix Smatch warnings. - lan78xx.c:2282 tx_complete() warn: variable dereferenced before check 'skb' (see line 2249) - lan78xx.c:2885 lan78xx_bh() info: ignoring unreachable code. - lan78xx.c:3159 lan78xx_probe() info: ignoring unreachable code. Reported-by: Dan Carpenter Signed-off-by: Woojung Huh --- drivers/net/usb/lan78xx.c | 52 ++- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index ec8bd34..3ac405f 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -291,7 +291,7 @@ static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) u32 *buf = kmalloc(sizeof(u32), GFP_KERNEL); int ret; - BUG_ON(!dev); + WARN_ON_ONCE(!dev); if (!buf) return -ENOMEM; @@ -319,7 +319,7 @@ static int lan78xx_write_reg(struct lan78xx_net *dev, u32 index, u32 data) u32 *buf = kmalloc(sizeof(u32), GFP_KERNEL); int ret; - BUG_ON(!dev); + WARN_ON_ONCE(!dev); if (!buf) return -ENOMEM; @@ -351,9 +351,9 @@ static int lan78xx_read_stats(struct lan78xx_net *dev, u32 *src; u32 *dst; - BUG_ON(!dev); - BUG_ON(!data); - BUG_ON(sizeof(struct lan78xx_statstage) != 0xBC); + WARN_ON_ONCE(!dev); + WARN_ON_ONCE(!data); + WARN_ON_ONCE(sizeof(struct lan78xx_statstage) != 0xBC); stats = kmalloc(sizeof(*stats), GFP_KERNEL); if (!stats) @@ -687,8 +687,8 @@ static int lan78xx_read_raw_eeprom(struct lan78xx_net *dev, u32 offset, u32 val; int i, ret; - BUG_ON(!dev); - BUG_ON(!data); + WARN_ON_ONCE(!dev); + WARN_ON_ONCE(!data); ret = lan78xx_eeprom_confirm_not_busy(dev); if (ret) @@ -737,8 +737,8 @@ static int lan78xx_write_raw_eeprom(struct lan78xx_net *dev, u32 offset, u32 val; int i, ret; - BUG_ON(!dev); - BUG_ON(!data); + WARN_ON_ONCE(!dev); + WARN_ON_ONCE(!data); ret = lan78xx_eeprom_confirm_not_busy(dev); if (ret) @@ -2221,19 +2221,19 @@ static enum skb_state defer_bh(struct lan78xx_net *dev, struct sk_buff *skb, old_state = entry->state; entry->state = state; if (!list->prev) - BUG_ON(!list->prev); + WARN_ON_ONCE(!list->prev); if (!list->next) - BUG_ON(!list->next); + WARN_ON_ONCE(!list->next); if (!skb->prev || !skb->next) - BUG_ON(true); + WARN_ON_ONCE(true); __skb_unlink(skb, list); spin_unlock(&list->lock); spin_lock(&dev->done.lock); if (!dev->done.prev) - BUG_ON(!dev->done.prev); + WARN_ON_ONCE(!dev->done.prev); if (!dev->done.next) - BUG_ON(!dev->done.next); + WARN_ON_ONCE(!dev->done.next); __skb_queue_tail(&dev->done, skb); if (skb_queue_len(&dev->done) == 1) @@ -2279,8 +2279,7 @@ static void tx_complete(struct urb *urb) usb_autopm_put_interface_async(dev->intf); - if (skb) - defer_bh(dev, skb, &dev->txq, tx_done); + defer_bh(dev, skb, &dev->txq, tx_done); } static void lan78xx_queue_skb(struct sk_buff_head *list, @@ -2295,13 +2294,15 @@ static void lan78xx_queue_skb(struct sk_buff_head *list, netdev_tx_t lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net) { struct lan78xx_net *dev = netdev_priv(net); + struct sk_buff *skb2 = NULL; - if (skb) + if (skb) { skb_tx_timestamp(skb); + skb2 = lan78xx_tx_prep(dev, skb, GFP_ATOMIC); + } - skb = lan78xx_tx_prep(dev, skb, GFP_ATOMIC); - if (skb) { - skb_queue_tail(&dev->txq_pend, skb); + if (skb2) { + skb_queue_tail(&dev->txq_pend, skb2); if (skb_queue_len(&dev->txq_pend) > 10) netif_stop_queue(net); @@ -2749,7 +2750,7 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) pos += roundup(skb2->len, sizeof(u32)); dev_kfree_skb(skb2); } else { - BUG_ON(true); + WARN_ON_ONCE(true); } } @@ -2859,9 +2860,9 @@ static void lan78xx_bh(unsigned long param) struct skb_data *entry; if (!dev->done.prev) - BUG_ON(!dev->done.prev); + WARN_ON_ONCE(!dev->done.prev); if (!dev->done.next) - BUG_ON(!dev->done.next); + WARN_ON_ONCE(!dev->done.next); while ((skb = skb_dequeue(&dev->done))) { entry = (struct skb_data *)(skb->cb); @@ -2882,10 +2883,6 @@ static void lan78xx_bh(unsigned long param) netdev_dbg(dev->net, "skb state %d\n", entry->state);
Re: [PATCH] sky2: Add module parameter for passing the MAC address
Liviu Dudau : > On Wed, Aug 05, 2015 at 05:40:57PM +0100, Stephen Hemminger wrote: [...] > > Yes, I can see that this can be a real problem, and other drivers > > solve the problem. The standard method is to assign a random mac address > > (and then let scripts overwrite) rather than introducing module parameter. > > Module parameters are discouraged because they are device specific. > > > > I agree. However, in my case, the boards people have assigned MAC addresses > to the chip, they just didn't built the board in such a way as to allow one > to store that MAC address in a permanent way :( And no, I can't use the DT > because the chip is actually on the PCIe bus. > > Even with the generation of a random address, it still needs to be copied > into the device, so I would guess that a version of the patch I've sent is > still relevant? Assuming a random address is generated, could you elaborate what is needed that sky2_set_mac_address fails to provide ? -- Ueimor -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] net: Unbreak resetting default values for tcp_wmem/udp_wmem_min
Commit 8133534c760d4083 ("net: limit tcp/udp rmem/wmem to SOCK_{RCV,SND}BUF_MIN") modified four sysctls to enforce that the values written to them are not less than SOCK_MIN_{RCV,SND}BUF. This change is fine for tcp_rmem and udp_rmem_min, since SOCK_MIN_RCVBUF is equal to equal to TCP_SKB_MIN_TRUESIZE. But it breaks tcp_wmem and udp_wmem_min for previously valid values because SOCK_MIN_SNDBUF is (2 * TCP_SKB_MIN_TRUESIZE), which ends up being greater than 4KB. Thus, 4096 is no longer accepted as a valid value, despite still being the default for udp_wmem_min, and for 'min' in tcp_wmem. A huge number of sysctl configurations at FB use 4096 as 'min', so this change breaks all of them. This patch changes the sysctls to simply enforce that the value written is greater than or equal to the default value of SK_MEM_QUANTUM. Fixes: 8133534c760d4083 ("net: limit tcp/udp rmem/wmem to SOCK_MIN...") Signed-off-by: Calvin Owens --- net/ipv4/sysctl_net_ipv4.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 433231c..a214b6a 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -41,8 +41,7 @@ static int tcp_syn_retries_min = 1; static int tcp_syn_retries_max = MAX_TCP_SYNCNT; static int ip_ping_group_range_min[] = { 0, 0 }; static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; -static int min_sndbuf = SOCK_MIN_SNDBUF; -static int min_rcvbuf = SOCK_MIN_RCVBUF; +static int min_buf = SK_MEM_QUANTUM; /* Update system visible IP port range */ static void set_local_port_range(struct net *net, int range[2]) @@ -530,7 +529,7 @@ static struct ctl_table ipv4_table[] = { .maxlen = sizeof(sysctl_tcp_wmem), .mode = 0644, .proc_handler = proc_dointvec_minmax, - .extra1 = &min_sndbuf, + .extra1 = &min_buf, }, { .procname = "tcp_notsent_lowat", @@ -545,7 +544,7 @@ static struct ctl_table ipv4_table[] = { .maxlen = sizeof(sysctl_tcp_rmem), .mode = 0644, .proc_handler = proc_dointvec_minmax, - .extra1 = &min_rcvbuf, + .extra1 = &min_buf, }, { .procname = "tcp_app_win", @@ -758,7 +757,7 @@ static struct ctl_table ipv4_table[] = { .maxlen = sizeof(sysctl_udp_rmem_min), .mode = 0644, .proc_handler = proc_dointvec_minmax, - .extra1 = &min_rcvbuf, + .extra1 = &min_buf, }, { .procname = "udp_wmem_min", @@ -766,7 +765,7 @@ static struct ctl_table ipv4_table[] = { .maxlen = sizeof(sysctl_udp_wmem_min), .mode = 0644, .proc_handler = proc_dointvec_minmax, - .extra1 = &min_sndbuf, + .extra1 = &min_buf, }, { } }; -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC] ipvlan: Problems with ipvlan and IPv6
Just doing: ip link add name ipvl0 link eth0 type ipvlan ip -6 addr add :0:0:1::0:1:1/128 dev ipvl0 ip addr add 192.168.1.1/32 dev iplv0 Before patch: ping :0:0:1::0:1:1 - No response, tcpdump on ipvl0 shows two copies of each ICMP echo request. ping 192.168.1.1 - Works, tcpdump on ipvl0 shows nothing With patch applied: ping :0:0:1::0:1:1 - Works, tcpdump on ipvl0 shows nothing ping 192.168.1.1 - Works, tcpdump on ipvl0 shows nothing Some other problems I'm seeing - Occurrence of "Dead loop on virtual device ipvl0, fix it urgently!" Running following script several times seems to get to the error. Once in this state machine is pretty locked up: rmmod ipvlan for i in `seq 0 199`; do ip link add name ipvl$i link eth0 type ipvlan addr=`echo $i | awk '{printf("%04x", $1)}'` ip -6 addr add :0:0:1::0:1:$addr/128 dev ipvl$i ifconfig ipvl$i up done - Seeing "Dropped {multi|broad}cast of type= [86dd]" Looks like this may be from ND messages. Might be innocuous I suppose, but it is annoying to see in logs. Signed-off-by: Tom Herbert --- drivers/net/ipvlan/ipvlan_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 207f62e..0b68538 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -277,8 +277,8 @@ static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb, skb->pkt_type = PACKET_HOST; if (local) { - if (dev_forward_skb(ipvlan->dev, skb) == NET_RX_SUCCESS) - success = true; + netif_receive_skb(skb); + success = true; } else { ret = RX_HANDLER_ANOTHER; success = true; @@ -384,7 +384,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) struct dst_entry *dst; int err, ret = NET_XMIT_DROP; struct flowi6 fl6 = { - .flowi6_iif = skb->dev->ifindex, + .flowi6_oif = dev_get_iflink(dev), .daddr = ip6h->daddr, .saddr = ip6h->saddr, .flowi6_flags = FLOWI_FLAG_ANYSRC, -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 09/10] net: Use VRF device index for socket lookups
Hi Tom: On 8/5/15 12:32 PM, Tom Herbert wrote: On Wed, Aug 5, 2015 at 10:14 AM, David Ahern wrote: >The intent of the VRF device is to leverage the existing SO_BINDTODEVICE >as a means of creating L3 domains. Since sockets are expected to be bound >to the VRF device the index of the master device needs to be used for >socket lookups. > This patch set seems awfully invasive at the socket layer. Isn't there anyway this functionality be contained in the routing layer and sockets use existing API? This patch is a leftover from earlier versions. It is no longer needed. Will drop for v5. David -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: rtnl_mutex deadlock?
On 08/05/2015 10:44 AM, Linus Torvalds wrote: On Wed, Aug 5, 2015 at 9:43 AM, Jiri Pirko wrote: Indeed. Most probably, NETLINK_CB(skb).portid got zeroed. Linus, are you able to reproduce this or is it a one-time issue? I don't think I'm able to reproduce this, it's happened only once so far. Here's a theory and patch below. Herbert, Thomas, does this make any sense to you resp. sound plausible? ;) I'm not quite sure what's best to return from here, i.e. whether we propagate -ENOMEM or instead retry over and over again hoping that the rehashing completed (and no new rehashing started in the mean time) ... The rehashing could take quite some time on large hashtables and given we can also fail with -ENOMEM from rhashtable_insert_rehash() when we cannot allocate a bucket table, it's probably okay to go with -ENOMEM? [PATCH net] netlink, rhashtable: fix deadlock when grabbing rtnl_mutex Linus reports the following deadlock on rtnl_mutex; triggered only once so far: [12236.694209] NetworkManager D 00013b80 0 1047 1 0x [12236.694218] 88003f902640 815d15a9 0018 [12236.694224] 880119538000 88003f902640 81a8ff84 [12236.694230] 81a8ff88 880119c47f00 815d133a 81a8ff80 [12236.694235] Call Trace: [12236.694250] [] ? schedule_preempt_disabled+0x9/0x10 [12236.694257] [] ? schedule+0x2a/0x70 [12236.694263] [] ? schedule_preempt_disabled+0x9/0x10 [12236.694271] [] ? __mutex_lock_slowpath+0x7f/0xf0 [12236.694280] [] ? mutex_lock+0x16/0x30 [12236.694291] [] ? rtnetlink_rcv+0x10/0x30 [12236.694299] [] ? netlink_unicast+0xfb/0x180 [12236.694309] [] ? rtnl_getlink+0x113/0x190 [12236.694319] [] ? rtnetlink_rcv_msg+0x7a/0x210 [12236.694331] [] ? sock_has_perm+0x5c/0x70 [12236.694339] [] ? rtnetlink_rcv+0x30/0x30 [12236.694346] [] ? netlink_rcv_skb+0x9c/0xc0 [12236.694354] [] ? rtnetlink_rcv+0x1f/0x30 [12236.694360] [] ? netlink_unicast+0xfb/0x180 [12236.694367] [] ? netlink_sendmsg+0x484/0x5d0 [12236.694376] [] ? __wake_up+0x2f/0x50 [12236.694387] [] ? sock_sendmsg+0x33/0x40 [12236.694396] [] ? ___sys_sendmsg+0x22e/0x240 [12236.694405] [] ? ___sys_recvmsg+0x135/0x1a0 [12236.694415] [] ? eventfd_write+0x82/0x210 [12236.694423] [] ? fsnotify+0x32e/0x4c0 [12236.694429] [] ? wake_up_q+0x60/0x60 [12236.694434] [] ? __sys_sendmsg+0x39/0x70 [12236.694440] [] ? entry_SYSCALL_64_fastpath+0x12/0x6a It seems so far plausible that the recursive call into rtnetlink_rcv() looks suspicious. One way, where this could trigger is that the senders NETLINK_CB(skb).portid was wrongly 0 (which is rtnetlink socket), so the rtnl_getlink() request's answer would be sent to the kernel instead to the actual user process, thus grabbing rtnl_mutex() twice. One theory how we could end up with a NETLINK_CB(skb).portid of 0 on a user space process is, when we start out from netlink_sendmsg() with an unbound portid, so that we need to do netlink_autobind(). Here, we would need to have an error of 0 returned, so that we can continue with sending the frame and setting NETLINK_CB(skb).portid to 0 eventually. I.e. in netlink_autobind(), we need to return with -EBUSY from netlink_insert(), so that the error code gets overwritten with 0. In order to get to this point, the inner __netlink_insert() must return with -EBUSY so that we reset the socket's portid to 0, and violate the 2nd rule documented in d470e3b483dc ("[NETLINK]: Fix two socket hashing bugs."), where it seemed to be a very similar issue that got fixed. There's one possibility where the rhashtable backend could in-fact return with -EBUSY. The insert is done via rhashtable_lookup_insert_key(), which invokes __rhashtable_insert_fast(). From here, we need to trigger the slow path with rhashtable_insert_rehash(), which can return -EBUSY in case a rehash of the hashtable is currently already in progress. This error propagates back to __netlink_insert() and provides us the needed precondition. Looks like the -EBUSY was introduced first in ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion"). So, as -EBUSY must not escape from there, we would need to remap it to a different error code for user space. As the current rhashtable cannot take any inserts in that case, it could be mapped to -ENOMEM. Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion") Reported-by: Linus Torvalds Signed-off-by: Daniel Borkmann --- net/netlink/af_netlink.c | 5 + 1 file changed, 5 insertions(+) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d8e2e39..1cfd4af 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1096,6 +1096,11 @@ static int netlink_insert(struct sock *sk, u32 portid) err = __netlink_insert(table, sk); if (err) { + /* Currently, a rehashing of rhashtable might be in progress, +* we however must not allow -EBUSY to
Re: [PATCH 09/10] net: Use VRF device index for socket lookups
On Wed, Aug 5, 2015 at 10:14 AM, David Ahern wrote: > The intent of the VRF device is to leverage the existing SO_BINDTODEVICE > as a means of creating L3 domains. Since sockets are expected to be bound > to the VRF device the index of the master device needs to be used for > socket lookups. > This patch set seems awfully invasive at the socket layer. Isn't there anyway this functionality be contained in the routing layer and sockets use existing API? Thanks, Tom > Signed-off-by: Shrijeet Mukherjee > Signed-off-by: David Ahern > --- > net/ipv4/syncookies.c | 5 - > net/ipv4/tcp_input.c | 6 +- > net/ipv4/tcp_ipv4.c | 11 +-- > 3 files changed, 18 insertions(+), 4 deletions(-) > > diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c > index d70b1f603692..e5c8b1240278 100644 > --- a/net/ipv4/syncookies.c > +++ b/net/ipv4/syncookies.c > @@ -18,6 +18,7 @@ > #include > #include > #include > +#include > > extern int sysctl_tcp_syncookies; > > @@ -348,7 +349,9 @@ struct sock *cookie_v4_check(struct sock *sk, struct > sk_buff *skb) > treq->snt_synack= tcp_opt.saw_tstamp ? tcp_opt.rcv_tsecr : 0; > treq->tfo_listener = false; > > - ireq->ir_iif = sk->sk_bound_dev_if; > + ireq->ir_iif = vrf_master_ifindex_by_index(sock_net(sk), > skb->skb_iif); > + if (!ireq->ir_iif) > + ireq->ir_iif = sk->sk_bound_dev_if; > > /* We throwed the options of the initial SYN away, so we hope > * the ACK carries the same options again (see RFC1122 4.2.3.8) > diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c > index 4e4d6bcd0ca9..6b96240a4055 100644 > --- a/net/ipv4/tcp_input.c > +++ b/net/ipv4/tcp_input.c > @@ -72,6 +72,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -6141,7 +6142,10 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, > tcp_openreq_init(req, &tmp_opt, skb, sk); > > /* Note: tcp_v6_init_req() might override ir_iif for link locals */ > - inet_rsk(req)->ir_iif = sk->sk_bound_dev_if; > + inet_rsk(req)->ir_iif = vrf_master_ifindex_by_index(sock_net(sk), > + skb->skb_iif); > + if (!inet_rsk(req)->ir_iif) > + inet_rsk(req)->ir_iif = sk->sk_bound_dev_if; > > af_ops->init_req(req, sk, skb); > > diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c > index d27eb549ced6..0f8ed98a2e64 100644 > --- a/net/ipv4/tcp_ipv4.c > +++ b/net/ipv4/tcp_ipv4.c > @@ -75,6 +75,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -682,6 +683,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct > sk_buff *skb) > */ > if (sk) > arg.bound_dev_if = sk->sk_bound_dev_if; > + if (!arg.bound_dev_if && skb->dev) > + arg.bound_dev_if = vrf_master_ifindex_rcu(skb->dev); > > arg.tos = ip_hdr(skb)->tos; > ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), > @@ -766,8 +769,10 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 > seq, u32 ack, > ip_hdr(skb)->saddr, /* XXX */ > arg.iov[0].iov_len, IPPROTO_TCP, 0); > arg.csumoffset = offsetof(struct tcphdr, check) / 2; > - if (oif) > - arg.bound_dev_if = oif; > + arg.bound_dev_if = oif ? : vrf_master_ifindex_rcu(skb_dst(skb)->dev); > + if (!arg.bound_dev_if) > + arg.bound_dev_if = vrf_master_ifindex_rcu(skb->dev); > + > arg.tos = tos; > ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), > skb, &TCP_SKB_CB(skb)->header.h4.opt, > @@ -1269,6 +1274,8 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, > struct sk_buff *skb, > ireq = inet_rsk(req); > sk_daddr_set(newsk, ireq->ir_rmt_addr); > sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); > + if (netif_index_is_vrf(sock_net(newsk), ireq->ir_iif)) > + newsk->sk_bound_dev_if = ireq->ir_iif; > newinet->inet_saddr = ireq->ir_loc_addr; > inet_opt = ireq->opt; > rcu_assign_pointer(newinet->inet_opt, inet_opt); > -- > 2.3.2 (Apple Git-55) > > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [ovs-dev] [PATCH net-next v3] openvswitch: Make 100 percents packets sampled when sampling rate is 1.
On Wed, Aug 5, 2015 at 12:30 AM, Wenyu Zhang wrote: > When sampling rate is 1, the sampling probability is UINT32_MAX. The packet > should be sampled even the prandom32() generate the number of UINT32_MAX. > And none packet need be sampled when the probability is 0. > > Signed-off-by: Wenyu Zhang Acked-by: Pravin B Shelar Thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [BUG] net/ipv4: inconsistent routing table
On 08/05/2015 02:06 AM, Daniel Borkmann wrote: [ please cc netdev ] On 08/05/2015 10:56 AM, Zang MingJie wrote: Hi: I found a bug when remove an ip address which is referenced by a routing entry. step to reproduce: ip li add type dummy ip li set dummy0 up ip ad add 10.0.0.1/24 dev dummy0 ip ad add 10.0.0.2/24 dev dummy0 Okay, so up to this point you have 2 addresses on the same subnet that are now on dummy0. ip ro add default via 10.0.0.2/24 This makes the default route go through 10.0.0.2. ip ad del 10.0.0.2/24 dev dummy0 Then you remove 10.0.0.2 from the local system, however since 10.0.0.1 is on the same subnet dummy0 would still be the correct interface to access 10.0.0.2 it is just no longer local to the system. after deleting the secondary ip address, the routing entry still pointing to 10.0.0.2 You didn't delete the default routing entry so why would you expect it to change? All you did is remove 10.0.0.2 from the local system. I believe the assumption is that 10.0.0.2 is still out there somewhere, it just isn't on the local system anymore. # ip ro default via 10.0.0.2 dev dummy0 10.0.0.0/24 dev dummy0 proto kernel scope link src 10.0.0.1 This matches up with what I would expect. 10.0.0.2 is the default gateway and it is accessible from dummy0 since 10.0.0.0/24 is accessible from dummy0. but actually, kernel considers the default route is directly connected. # ip ro get 1.1.1.1 1.1.1.1 dev dummy0 src 10.0.0.1 cache I'm not sure how you came to the "directly connected" conclusion. It is still routing things out through 10.0.0.2 from 10.0.0.1. Maybe your example would work better if you used 10.0.0.1 and 10.0.1.1 instead. Then I think you might be able to better see that when you delete the second address the route would be broken. - Alex -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sky2: Add module parameter for passing the MAC address
On Wed, Aug 05, 2015 at 06:15:37PM +0100, Ryan Harkin wrote: >On 5 August 2015 at 16:50, Liviu Dudau <[1]liviu.du...@arm.com> wrote: > > For designs where EEPROMs are not connected to PCI Yukon2 > chips we need to get the MAC address from the firmware. > Add a module parameter called 'mac_address' for this. It > will be used if no DT node can be found and the B2_MAC > register holds an invalid value. > > Signed-off-by: Liviu Dudau <[2]liviu.du...@arm.com> > >Looks good to me. FWIW, you can have a tested or reviewed-by at your > preference: >Tested-by: Ryan Harkin <[3]ryan.har...@linaro.org> >Reviewed-by: Ryan Harkin <[4]ryan.har...@linaro.org> > Thanks Ryan, I think one can provide both tags, so I will use them together. Best regards, Liviu > > > --- > drivers/net/ethernet/marvell/sky2.c | 14 +- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/marvell/sky2.c > b/drivers/net/ethernet/marvell/sky2.c > index d9f4498..a977d95 100644 > --- a/drivers/net/ethernet/marvell/sky2.c > +++ b/drivers/net/ethernet/marvell/sky2.c > @@ -101,6 +101,10 @@ static int legacy_pme = 0; > module_param(legacy_pme, int, 0); > MODULE_PARM_DESC(legacy_pme, "Legacy power management"); > > +/* Ugh! Let the firmware tell us the hardware address */ > +static int mac_address[ETH_ALEN] = { 0, }; > +module_param_array(mac_address, int, NULL, 0); > + > static const struct pci_device_id sky2_id_table[] = { > { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ > { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ > @@ -4811,13 +4815,21 @@ static struct net_device > *sky2_init_netdev(struct sky2_hw *hw, unsigned port, > /* try to get mac address in the following order: > * 1) from device tree data > * 2) from internal registers set by bootloader > + * 3) from the command line parameter > */ > iap = of_get_mac_address(hw->pdev->dev.of_node); > if (iap) > memcpy(dev->dev_addr, iap, ETH_ALEN); > - else > + else { > memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port > * 8, > ETH_ALEN); > + if (!is_valid_ether_addr(&dev->dev_addr[0])) { > + int i; > + > + for (i = 0; i < ETH_ALEN; i++) > + dev->dev_addr[i] = mac_address[i]; > + } > + } > > return dev; > } > -- > 2.4.6 > > References > >Visible links >1. mailto:liviu.du...@arm.com >2. mailto:liviu.du...@arm.com >3. mailto:ryan.har...@linaro.org >4. mailto:ryan.har...@linaro.org -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --- ¯\_(ツ)_/¯ -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sky2: Add module parameter for passing the MAC address
On Wed, Aug 05, 2015 at 05:40:57PM +0100, Stephen Hemminger wrote: > On Wed, 5 Aug 2015 16:50:54 +0100 > Liviu Dudau wrote: > > > For designs where EEPROMs are not connected to PCI Yukon2 > > chips we need to get the MAC address from the firmware. > > Add a module parameter called 'mac_address' for this. It > > will be used if no DT node can be found and the B2_MAC > > register holds an invalid value. > > > > Signed-off-by: Liviu Dudau > > Yes, I can see that this can be a real problem, and other drivers > solve the problem. The standard method is to assign a random mac address > (and then let scripts overwrite) rather than introducing module parameter. > Module parameters are discouraged because they are device specific. > I agree. However, in my case, the boards people have assigned MAC addresses to the chip, they just didn't built the board in such a way as to allow one to store that MAC address in a permanent way :( And no, I can't use the DT because the chip is actually on the PCIe bus. Even with the generation of a random address, it still needs to be copied into the device, so I would guess that a version of the patch I've sent is still relevant? Best regards, Liviu > > -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --- ¯\_(ツ)_/¯ -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/10] net: Fix up inet_addr_type checks
Currently inet_addr_type and inet_dev_addr_type expect local addresses to be in the local table. With the VRF device local routes for devices associated with a VRF will be in the table associated with the VRF. Provide an alternate inet_addr lookup to use a specific table rather than defaulting to the local table. inet_addr_type_dev_table keeps the same semantics as inet_addr_type but if the passed in device is enslaved to a VRF then the table for that VRF is used for the lookup. Signed-off-by: David Ahern --- include/net/route.h | 3 +++ net/ipv4/af_inet.c | 13 - net/ipv4/arp.c | 15 +-- net/ipv4/fib_frontend.c | 28 +--- net/ipv4/fib_semantics.c | 6 -- net/ipv4/icmp.c | 5 +++-- 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 6ba681f0b98d..6dda2c1bf8c6 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -192,6 +192,9 @@ unsigned int inet_addr_type(struct net *net, __be32 addr); unsigned int inet_addr_type_table(struct net *net, __be32 addr, int tb_id); unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr); +unsigned int inet_addr_type_dev_table(struct net *net, + const struct net_device *dev, + __be32 addr); void ip_rt_multicast_event(struct in_device *); int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg); void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index cc4e498a0ccf..96fba4f63454 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -119,6 +119,7 @@ #ifdef CONFIG_IP_MROUTE #include #endif +#include /* The inetsw table contains everything that inet_create needs to @@ -427,6 +428,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct net *net = sock_net(sk); unsigned short snum; int chk_addr_ret; + int tb_id = 0; int err; /* If the socket has its own bind function then use it. (RAW) */ @@ -448,7 +450,16 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) goto out; } - chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr); + if (sk->sk_bound_dev_if) { + struct net_device *dev; + + rcu_read_lock(); + dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if); + if (dev) + tb_id = vrf_dev_table_rcu(dev); + rcu_read_unlock(); + } + chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id); /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 34a308573f4b..30409b75e925 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -233,7 +233,7 @@ static int arp_constructor(struct neighbour *neigh) return -EINVAL; } - neigh->type = inet_addr_type(dev_net(dev), addr); + neigh->type = inet_addr_type_dev_table(dev_net(dev), dev, addr); parms = in_dev->arp_parms; __neigh_parms_put(neigh->parms); @@ -343,7 +343,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) switch (IN_DEV_ARP_ANNOUNCE(in_dev)) { default: case 0: /* By default announce any local IP */ - if (skb && inet_addr_type(dev_net(dev), + if (skb && inet_addr_type_dev_table(dev_net(dev), dev, ip_hdr(skb)->saddr) == RTN_LOCAL) saddr = ip_hdr(skb)->saddr; break; @@ -351,7 +351,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) if (!skb) break; saddr = ip_hdr(skb)->saddr; - if (inet_addr_type(dev_net(dev), saddr) == RTN_LOCAL) { + if (inet_addr_type_dev_table(dev_net(dev), dev, +saddr) == RTN_LOCAL) { /* saddr should be known to target */ if (inet_addr_onlink(in_dev, target, saddr)) break; @@ -751,7 +752,7 @@ static int arp_process(struct sock *sk, struct sk_buff *skb) /* Special case: IPv4 duplicate address detection packet (RFC2131) */ if (sip == 0) { if (arp->ar_op == htons(ARPOP_REQUEST) && - inet_addr_type(net, tip) == RTN_LOCAL && + inet_addr_type_dev_table(net, dev, tip) == RTN_LOCAL && !arp_ignore(in_dev, sip, tip)) arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
[PATCH 07/10] net: Add routes to the table associated with the device
When a device associated with a VRF is brought up or down routes should be added to/removed from the table associated with the VRF. fib_magic defaults to using the main or local tables. Have it use the table with the device if there is one. A part of this is directing prefsrc validations to the correct table as well. Signed-off-by: David Ahern --- net/ipv4/fib_frontend.c | 8 net/ipv4/fib_semantics.c | 25 +++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index d84ae0e30369..0a50a08ab844 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -803,6 +803,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa) { struct net *net = dev_net(ifa->ifa_dev->dev); + int tb_id = vrf_dev_table_rtnl(ifa->ifa_dev->dev); struct fib_table *tb; struct fib_config cfg = { .fc_protocol = RTPROT_KERNEL, @@ -817,11 +818,10 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad }, }; - if (type == RTN_UNICAST) - tb = fib_new_table(net, RT_TABLE_MAIN); - else - tb = fib_new_table(net, RT_TABLE_LOCAL); + if (!tb_id) + tb_id = (type == RTN_UNICAST) ? RT_TABLE_MAIN : RT_TABLE_LOCAL; + tb = fib_new_table(net, tb_id); if (!tb) return; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 410ddb67221e..85e9a8abf15c 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -838,6 +838,23 @@ __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh) return nh->nh_saddr; } +static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc) +{ + if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst || + fib_prefsrc != cfg->fc_dst) { + int tb_id = cfg->fc_table; + + if (tb_id == RT_TABLE_MAIN) + tb_id = RT_TABLE_LOCAL; + + if (inet_addr_type_table(cfg->fc_nlinfo.nl_net, +fib_prefsrc, tb_id) != RTN_LOCAL) { + return false; + } + } + return true; +} + struct fib_info *fib_create_info(struct fib_config *cfg) { int err; @@ -1033,12 +1050,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) fi->fib_flags |= RTNH_F_LINKDOWN; } - if (fi->fib_prefsrc) { - if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst || - fi->fib_prefsrc != cfg->fc_dst) - if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL) - goto err_inval; - } + if (fi->fib_prefsrc && !fib_valid_prefsrc(cfg, fi->fib_prefsrc)) + goto err_inval; change_nexthops(fi) { fib_info_update_nh_saddr(net, nexthop_nh); -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/10] udp: Handle VRF device
For unconnected UDP sockets using a VRF device lookup source address based on VRF table. This allows the UDP header to be properly setup before showing up at the VRF device via the dst. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- net/ipv4/udp.c | 25 +++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 83aa604f9273..b513d72a21b3 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -884,7 +884,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) struct rtable *rt = NULL; int free = 0; int connected = 0; - __be32 daddr, faddr, saddr; + __be32 daddr, faddr, saddr, vsaddr = 0; __be16 dport; u8 tos; int err, is_udplite = IS_UDPLITE(sk); @@ -1013,11 +1013,30 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) if (!rt) { struct net *net = sock_net(sk); + __u8 flow_flags = inet_sk_flowi_flags(sk); fl4 = &fl4_stack; + + /* unconnected socket. If output device is enslaved to a VRF +* device lookup source address from VRF table. This mimics +* behavior of ip_route_connect{_init}. +*/ + if (netif_index_is_vrf(net, ipc.oif)) { + flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos, + RT_SCOPE_UNIVERSE, sk->sk_protocol, + (flow_flags | FLOWI_FLAG_VRFSRC), + faddr, saddr, dport, inet->inet_sport); + + rt = ip_route_output_flow(net, fl4, sk); + if (!IS_ERR(rt)) { + vsaddr = fl4->saddr; + ip_rt_put(rt); + } + } + flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, sk->sk_protocol, - inet_sk_flowi_flags(sk), + flow_flags, faddr, saddr, dport, inet->inet_sport); security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); @@ -1042,6 +1061,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) goto do_confirm; back_from_confirm: + if (vsaddr) + fl4->saddr = vsaddr; saddr = fl4->saddr; if (!ipc.addr) daddr = ipc.addr = fl4->daddr; -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/10] net: Use VRF device index for socket lookups
The intent of the VRF device is to leverage the existing SO_BINDTODEVICE as a means of creating L3 domains. Since sockets are expected to be bound to the VRF device the index of the master device needs to be used for socket lookups. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- net/ipv4/syncookies.c | 5 - net/ipv4/tcp_input.c | 6 +- net/ipv4/tcp_ipv4.c | 11 +-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index d70b1f603692..e5c8b1240278 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -18,6 +18,7 @@ #include #include #include +#include extern int sysctl_tcp_syncookies; @@ -348,7 +349,9 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) treq->snt_synack= tcp_opt.saw_tstamp ? tcp_opt.rcv_tsecr : 0; treq->tfo_listener = false; - ireq->ir_iif = sk->sk_bound_dev_if; + ireq->ir_iif = vrf_master_ifindex_by_index(sock_net(sk), skb->skb_iif); + if (!ireq->ir_iif) + ireq->ir_iif = sk->sk_bound_dev_if; /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 4e4d6bcd0ca9..6b96240a4055 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -6141,7 +6142,10 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, tcp_openreq_init(req, &tmp_opt, skb, sk); /* Note: tcp_v6_init_req() might override ir_iif for link locals */ - inet_rsk(req)->ir_iif = sk->sk_bound_dev_if; + inet_rsk(req)->ir_iif = vrf_master_ifindex_by_index(sock_net(sk), + skb->skb_iif); + if (!inet_rsk(req)->ir_iif) + inet_rsk(req)->ir_iif = sk->sk_bound_dev_if; af_ops->init_req(req, sk, skb); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index d27eb549ced6..0f8ed98a2e64 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include @@ -682,6 +683,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) */ if (sk) arg.bound_dev_if = sk->sk_bound_dev_if; + if (!arg.bound_dev_if && skb->dev) + arg.bound_dev_if = vrf_master_ifindex_rcu(skb->dev); arg.tos = ip_hdr(skb)->tos; ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), @@ -766,8 +769,10 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, ip_hdr(skb)->saddr, /* XXX */ arg.iov[0].iov_len, IPPROTO_TCP, 0); arg.csumoffset = offsetof(struct tcphdr, check) / 2; - if (oif) - arg.bound_dev_if = oif; + arg.bound_dev_if = oif ? : vrf_master_ifindex_rcu(skb_dst(skb)->dev); + if (!arg.bound_dev_if) + arg.bound_dev_if = vrf_master_ifindex_rcu(skb->dev); + arg.tos = tos; ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), skb, &TCP_SKB_CB(skb)->header.h4.opt, @@ -1269,6 +1274,8 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, ireq = inet_rsk(req); sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); + if (netif_index_is_vrf(sock_net(newsk), ireq->ir_iif)) + newsk->sk_bound_dev_if = ireq->ir_iif; newinet->inet_saddr = ireq->ir_loc_addr; inet_opt = ireq->opt; rcu_assign_pointer(newinet->inet_opt, inet_opt); -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/10] net: Introduce VRF device driver
This driver borrows heavily from IPvlan and teaming drivers. Routing domains (VRF-lite) are created by instantiating a VRF master device with an associated table and enslaving all routed interfaces that participate in the domain. As part of the enslavement, all connected routes for the enslaved devices are moved to the table associated with the VRF device. Outgoing sockets must bind to the VRF device to function. Standard FIB rules bind the VRF device to tables and regular fib rule processing is followed. Routed traffic through the box, is forwarded by using the VRF device as the IIF and following the IIF rule to a table that is mated with the VRF. Example: Create vrf 1: ip link add vrf1 type vrf table 5 ip rule add iif vrf1 table 5 ip rule add oif vrf1 table 5 ip route add table 5 prohibit default ip link set vrf1 up Add interface to vrf 1: ip link set eth1 master vrf1 Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- drivers/net/Kconfig | 7 + drivers/net/Makefile | 1 + drivers/net/vrf.c| 715 +++ include/net/vrf.h| 1 - 4 files changed, 723 insertions(+), 1 deletion(-) create mode 100644 drivers/net/vrf.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c18f9e62a9fa..e58468b02987 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -297,6 +297,13 @@ config NLMON diagnostics, etc. This is mostly intended for developers or support to debug netlink issues. If unsure, say N. +config NET_VRF + tristate "Virtual Routing and Forwarding (Lite)" + depends on IP_MULTIPLE_TABLES && IPV6_MULTIPLE_TABLES + ---help--- + This option enables the support for mapping interfaces into VRF's. The + support enables VRF devices. + endif # NET_CORE config SUNGEM_PHY diff --git a/drivers/net/Makefile b/drivers/net/Makefile index c12cb22478a7..ca16dd689b36 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o obj-$(CONFIG_VXLAN) += vxlan.o obj-$(CONFIG_GENEVE) += geneve.o obj-$(CONFIG_NLMON) += nlmon.o +obj-$(CONFIG_NET_VRF) += vrf.o # # Networking Drivers diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c new file mode 100644 index ..75c06ee2efa3 --- /dev/null +++ b/drivers/net/vrf.c @@ -0,0 +1,715 @@ +/* + * vrf.c: device driver to encapsulate a VRF space + * + * Copyright (c) 2015 Cumulus Networks. All rights reserved. + * Copyright (c) 2015 Shrijeet Mukherjee + * Copyright (c) 2015 David Ahern + * + * Based on dummy, team and ipvlan drivers + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "vrf" +#define DRV_VERSION"1.0" + +#define vrf_is_slave(dev) ((dev)->flags & IFF_SLAVE) + +#define vrf_master_get_rcu(dev) \ + ((struct net_device *)rcu_dereference(dev->rx_handler_data)) + +struct pcpu_dstats { + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drps; + u64 rx_pkts; + u64 rx_bytes; + struct u64_stats_sync syncp; +}; + +static struct dst_entry *vrf_ip_check(struct dst_entry *dst, u32 cookie) +{ + return dst; +} + +static int vrf_ip_local_out(struct sk_buff *skb) +{ + return ip_local_out(skb); +} + +static unsigned int vrf_v4_mtu(const struct dst_entry *dst) +{ + /* TO-DO: return max ethernet size? */ + return dst->dev->mtu; +} + +static void vrf_dst_destroy(struct dst_entry *dst) +{ + /* our dst lives forever - or until the device is closed */ +} + +static unsigned int vrf_default_advmss(const struct dst_entry *dst) +{ + return 65535 - 40; +} + +static struct dst_ops vrf_dst_ops = { + .family = AF_INET, + .local_out = vrf_ip_local_out, + .check = vrf_ip_check, + .mtu= vrf_v4_mtu, + .destroy= vrf_dst_destroy, + .default_advmss = vrf_default_advmss, +}; + +static bool is_ip_rx_frame(struct sk_buff *skb) +{ + switch (skb->protocol) { + case htons(ETH_P_IP): + case htons(ETH_P_IPV6): + return true; + } + return false; +} + +/* note: already called with rcu_read_lock */ +static rx_handler_result_t vrf_handle_frame(struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + + if (is_ip_rx_frame(skb)) { + struct net_device *dev = vrf_master_get_rcu(skb->dev); +
[PATCH 02/10] net: Use VRF device index for lookups on RX
On ingress use index of VRF master device for route lookups if real device is enslaved. Rules are expected to be installed for the VRF device to direct lookups to a specific table. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- net/ipv4/fib_frontend.c | 8 +++- net/ipv4/route.c| 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 6b98de0d7949..d8ced1d89f1b 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -45,6 +45,7 @@ #include #include #include +#include #ifndef CONFIG_IP_MULTIPLE_TABLES @@ -309,7 +310,9 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, bool dev_match; fl4.flowi4_oif = 0; - fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX; + fl4.flowi4_iif = vrf_master_ifindex_rcu(dev); + if (!fl4.flowi4_iif) + fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX; fl4.daddr = src; fl4.saddr = dst; fl4.flowi4_tos = tos; @@ -339,6 +342,9 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, if (nh->nh_dev == dev) { dev_match = true; break; + } else if (vrf_master_ifindex_rcu(nh->nh_dev) == dev->ifindex) { + dev_match = true; + break; } } #else diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 18fd7c9095c7..c26ff1f7067d 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -112,6 +112,7 @@ #endif #include #include +#include #define RT_FL_TOS(oldflp4) \ ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)) @@ -1726,7 +1727,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, * Now we are ready to route packet. */ fl4.flowi4_oif = 0; - fl4.flowi4_iif = dev->ifindex; + fl4.flowi4_iif = vrf_master_ifindex_rcu(dev) ? : dev->ifindex; fl4.flowi4_mark = skb->mark; fl4.flowi4_tos = tos; fl4.flowi4_scope = RT_SCOPE_UNIVERSE; -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/10] net: Add inet_addr lookup by table
Currently inet_addr_type and inet_dev_addr_type expect local addresses to be in the local table. With the VRF device local routes for devices associated with a VRF will be in the table associated with the VRF. Provide an alternate inet_addr lookup to use a specific table rather than defaulting to the local table. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- include/net/route.h | 1 + net/ipv4/fib_frontend.c | 22 +++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 94189d4bd899..6ba681f0b98d 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -189,6 +189,7 @@ void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk); void ip_rt_send_redirect(struct sk_buff *skb); unsigned int inet_addr_type(struct net *net, __be32 addr); +unsigned int inet_addr_type_table(struct net *net, __be32 addr, int tb_id); unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr); void ip_rt_multicast_event(struct in_device *); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index d8ced1d89f1b..b11321a8e58d 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -212,12 +212,12 @@ void fib_flush_external(struct net *net) */ static inline unsigned int __inet_dev_addr_type(struct net *net, const struct net_device *dev, - __be32 addr) + __be32 addr, int tb_id) { struct flowi4 fl4 = { .daddr = addr }; struct fib_result res; unsigned int ret = RTN_BROADCAST; - struct fib_table *local_table; + struct fib_table *table; if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr)) return RTN_BROADCAST; @@ -226,10 +226,10 @@ static inline unsigned int __inet_dev_addr_type(struct net *net, rcu_read_lock(); - local_table = fib_get_table(net, RT_TABLE_LOCAL); - if (local_table) { + table = fib_get_table(net, tb_id); + if (table) { ret = RTN_UNICAST; - if (!fib_table_lookup(local_table, &fl4, &res, FIB_LOOKUP_NOREF)) { + if (!fib_table_lookup(table, &fl4, &res, FIB_LOOKUP_NOREF)) { if (!dev || dev == res.fi->fib_dev) ret = res.type; } @@ -239,16 +239,24 @@ static inline unsigned int __inet_dev_addr_type(struct net *net, return ret; } +unsigned int inet_addr_type_table(struct net *net, __be32 addr, int tb_id) +{ + return __inet_dev_addr_type(net, NULL, addr, tb_id); +} +EXPORT_SYMBOL(inet_addr_type_table); + unsigned int inet_addr_type(struct net *net, __be32 addr) { - return __inet_dev_addr_type(net, NULL, addr); + return __inet_dev_addr_type(net, NULL, addr, RT_TABLE_LOCAL); } EXPORT_SYMBOL(inet_addr_type); unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr) { - return __inet_dev_addr_type(net, dev, addr); + int rt_table = vrf_dev_table(dev) ? : RT_TABLE_LOCAL; + + return __inet_dev_addr_type(net, dev, addr, rt_table); } EXPORT_SYMBOL(inet_dev_addr_type); -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/10] net: Use VRF device index for lookups on TX
As with ingress use the index of VRF master device for route lookups on egress. However, the oif should only be used to direct the lookups to a specific table. Routes in the table are not based on the VRF device but rather interfaces that are part of the VRF so do not consider the oif for lookups within the table. The FLOWI_FLAG_VRFSRC is used to control this latter part. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- include/net/flow.h | 1 + include/net/route.h | 3 +++ net/ipv4/fib_trie.c | 7 +-- net/ipv4/icmp.c | 4 net/ipv4/route.c| 5 + 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/net/flow.h b/include/net/flow.h index 3098ae33a178..f305588fc162 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -33,6 +33,7 @@ struct flowi_common { __u8flowic_flags; #define FLOWI_FLAG_ANYSRC 0x01 #define FLOWI_FLAG_KNOWN_NH0x02 +#define FLOWI_FLAG_VRFSRC 0x04 __u32 flowic_secid; struct flowi_tunnel flowic_tun_key; }; diff --git a/include/net/route.h b/include/net/route.h index 2d45f419477f..94189d4bd899 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -251,6 +251,9 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 if (inet_sk(sk)->transparent) flow_flags |= FLOWI_FLAG_ANYSRC; + if (netif_index_is_vrf(sock_net(sk), oif)) + flow_flags |= FLOWI_FLAG_VRFSRC; + flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, protocol, flow_flags, dst, src, dport, sport); } diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 37c4bb89a708..1243c79cb5b0 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1423,8 +1423,11 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, nh->nh_flags & RTNH_F_LINKDOWN && !(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE)) continue; - if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif) - continue; + if (!(flp->flowi4_flags & FLOWI_FLAG_VRFSRC)) { + if (flp->flowi4_oif && + flp->flowi4_oif != nh->nh_oif) + continue; + } if (!(fib_flags & FIB_LOOKUP_NOREF)) atomic_inc(&fi->fib_clntref); diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c0556f1e4bf0..1164fc4ce3bc 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -96,6 +96,7 @@ #include #include #include +#include /* * Build xmit assembly blocks @@ -425,6 +426,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) fl4.flowi4_mark = mark; fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); fl4.flowi4_proto = IPPROTO_ICMP; + fl4.flowi4_oif = vrf_master_ifindex_rcu(skb->dev) ? : skb->dev->ifindex; security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); rt = ip_route_output_key(net, &fl4); if (IS_ERR(rt)) @@ -458,6 +460,8 @@ static struct rtable *icmp_route_lookup(struct net *net, fl4->flowi4_proto = IPPROTO_ICMP; fl4->fl4_icmp_type = type; fl4->fl4_icmp_code = code; + fl4->flowi4_oif = vrf_master_ifindex_rcu(skb_in->dev) ? : skb_in->dev->ifindex; + security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4)); rt = __ip_route_output_key(net, fl4); if (IS_ERR(rt)) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c26ff1f7067d..2c89d294b669 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2131,6 +2131,11 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4) fl4->saddr = inet_select_addr(dev_out, 0, RT_SCOPE_HOST); } + if (netif_is_vrf(dev_out) && + !(fl4->flowi4_flags & FLOWI_FLAG_VRFSRC)) { + rth = vrf_dev_get_rth(dev_out); + goto out; + } } if (!fl4->daddr) { -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/10] net: Introduce VRF related flags and helpers
Add a VRF_MASTER flag for interfaces and helper functions for determining if a device is a VRF_MASTER. Add link attribute for passing VRF_TABLE id. Add vrf_ptr to netdevice. Add various macros for determining if a device is a VRF device, the index of the master VRF device and table associated with VRF device. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- include/linux/netdevice.h| 20 + include/net/vrf.h| 177 +++ include/uapi/linux/if_link.h | 9 +++ 3 files changed, 206 insertions(+) create mode 100644 include/net/vrf.h diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 607b5f41f46f..f7a6ef2fae3a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1289,6 +1289,7 @@ enum netdev_priv_flags { IFF_XMIT_DST_RELEASE_PERM = 1<<22, IFF_IPVLAN_MASTER = 1<<23, IFF_IPVLAN_SLAVE= 1<<24, + IFF_VRF_MASTER = 1<<25, }; #define IFF_802_1Q_VLANIFF_802_1Q_VLAN @@ -1316,6 +1317,7 @@ enum netdev_priv_flags { #define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM #define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER #define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE +#define IFF_VRF_MASTER IFF_VRF_MASTER /** * struct net_device - The DEVICE structure. @@ -1432,6 +1434,7 @@ enum netdev_priv_flags { * @dn_ptr:DECnet specific data * @ip6_ptr: IPv6 specific data * @ax25_ptr: AX.25 specific data + * @vrf_ptr: VRF specific data * @ieee80211_ptr: IEEE 802.11 specific data, assign before registering * * @last_rx: Time of last Rx @@ -1650,6 +1653,7 @@ struct net_device { struct dn_dev __rcu *dn_ptr; struct inet6_dev __rcu *ip6_ptr; void*ax25_ptr; + struct net_vrf_dev __rcu *vrf_ptr; struct wireless_dev *ieee80211_ptr; struct wpan_dev *ieee802154_ptr; #if IS_ENABLED(CONFIG_MPLS_ROUTING) @@ -3808,6 +3812,22 @@ static inline bool netif_supports_nofcs(struct net_device *dev) return dev->priv_flags & IFF_SUPP_NOFCS; } +static inline bool netif_is_vrf(const struct net_device *dev) +{ + return dev->priv_flags & IFF_VRF_MASTER; +} + +static inline bool netif_index_is_vrf(struct net *net, int ifindex) +{ + struct net_device *dev = dev_get_by_index_rcu(net, ifindex); + bool rc = false; + + if (dev) + rc = netif_is_vrf(dev); + + return rc; +} + /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */ static inline void netif_keep_dst(struct net_device *dev) { diff --git a/include/net/vrf.h b/include/net/vrf.h new file mode 100644 index ..5d4bd67a4902 --- /dev/null +++ b/include/net/vrf.h @@ -0,0 +1,177 @@ +/* + * include/net/net_vrf.h - adds vrf dev structure definitions + * Copyright (c) 2015 Cumulus Networks + * + * 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 __LINUX_NET_VRF_H +#define __LINUX_NET_VRF_H + +struct net_vrf_dev { + struct rcu_head rcu; + int ifindex; /* ifindex of master dev */ + u32 tb_id; /* table id for VRF */ +}; + +struct slave { + struct list_headlist; + struct net_device *dev; +}; + +struct slave_queue { + struct list_headall_slaves; + int num_slaves; +}; + +struct net_vrf { + struct slave_queue queue; + struct fib_table*tb; + struct rtable *rth; + u32 tb_id; +}; + + +#if IS_ENABLED(CONFIG_NET_VRF) +/* called with rcu_read_lock() */ +static inline int vrf_master_ifindex_rcu(const struct net_device *dev) +{ + struct net_vrf_dev *vrf_ptr; + int ifindex = 0; + + if (!dev) + return 0; + + if (netif_is_vrf(dev)) + ifindex = dev->ifindex; + else { + vrf_ptr = rcu_dereference(dev->vrf_ptr); + if (vrf_ptr) + ifindex = vrf_ptr->ifindex; + } + + return ifindex; +} + +static inline int vrf_master_ifindex(const struct net_device *dev) +{ + int ifindex; + + rcu_read_lock(); + ifindex = vrf_master_ifindex_rcu(dev); + rcu_read_unlock(); + + return ifindex; +} + +static inline int vrf_master_ifindex_by_index(struct net *net, int ifindex) +{ + int rc = 0; + + if (ifindex) { + struct net_device *dev = dev_get_by_index(net, ifindex); + + if (dev) { + rc = vrf_master_ifindex(dev); +
[PATCH net-next 00/10] VRF-lite - v4
In the context of internet scale routing a requirement that always comes up is the need to partition the available routing tables into disjoint routing planes. A specific use case is the multi-tenancy problem where each tenant has their own unique routing tables and in the very least need different default gateways. This patch allows the ability to create virtual router domains (aka VRFs (VRF-lite to be specific) in the linux packet forwarding stack. The main observation is that through the use of rules and socket binding to interfaces, all the facilities that we need are already present in the infrastructure. What is missing is a handle that identifies a routing domain and can be used to gather applicable rules/tables and uniqify neighbor selection. The scheme used needs to preserves the notions of ECMP, and general routing principles. This driver is a cross between functionality that the IPVLAN driver and the Team drivers provide where a device is created and packets into/out of the routing domain are shuttled through this device. The device is then used as a handle to identify the applicable rules. The VRF device is thus the layer3 equivalent of a vlan device. The very important point to note is that this is only a Layer3 concept so L2 tools (e.g., LLDP) do not need to be run in each VRF, processes can run in unaware mode or select a VRF to be talking through. Also the behavioral model is a generalized application of the familiar VRF-Lite model with some performance paths that need optimization. (Specifically the output route selector that Roopa, Robert, Thomas and EricB are currently discussing on the MPLS thread) High Level points = 1. Simple overlay driver (minimal changes to current stack) * uses the existing fib tables and fib rules infrastructure 2. Modelled closely after the ipvlan driver 3. Uses current API and infrastructure. * Applications can use SO_BINDTODEVICE or cmsg device indentifiers to pick VRF (ping, traceroute just work) * Standard IP Rules work, and since they are aggregated against the device, scale is manageable 4. Completely orthogonal to Namespaces and only provides separation in the routing plane (and ARP) N2 N1 (all configs here) +---+ +--+ | | |swp1 :10.0.1.1+--+swp1 :10.0.1.2 | | | | | |swp2 :10.0.2.1+--+swp2 :10.0.2.2 | | | +---+ | VRF 1| | table 5 | | | +---+ | | | VRF 2| N3 | table 6 | +---+ | | | | |swp3 :10.0.2.1+--+swp1 :10.0.2.2 | | | | | |swp4 :10.0.3.1+--+swp2 :10.0.3.2 | +--+ +---+ Given the topology above, the setup needed to get the basic VRF functions working would be Create the VRF devices and associate with a table ip link add vrf1 type vrf table 5 ip link add vrf2 type vrf table 6 Install the lookup rules that map table to VRF domain ip rule add pref 200 oif vrf1 lookup 5 ip rule add pref 200 iif vrf1 lookup 5 ip rule add pref 200 oif vrf2 lookup 6 ip rule add pref 200 iif vrf2 lookup 6 ip link set vrf1 up ip link set vrf2 up Enslave the routing member interfaces ip link set swp1 master vrf1 ip link set swp2 master vrf1 ip link set swp3 master vrf2 ip link set swp4 master vrf2 Connected and local routes are automatically moved from main and local tables to the VRF table. ping using VRF0 is simply ping -I vrf0 10.0.1.2 Design Highlights = If a device is enslaved to a VRF device (ie., associated with a VRF) then: 1. Rx path The master device index is used as the iif for all lookups. 2. Tx path Similarly, for Tx the VRF device oif is used in the flow to direct lookups to the table associated with the VRF via its rule. From there the FLOWI_FLAG_VRFSRC flag is used to indicate that the oif should not be used for FIB table lookups. 3. Connected and local routes On link up for a device, connected and local routes are added to the table associated with the VRF device, rather than the local and main tables. 4. Socket lookups Socket lookups use the VRF device for comparison with sk_bound_dev_if. If a socket is not bound to a device a socket match can happen based on destination address, port and protocol in which case a VRF global or agnostic process handles the connection (ie., this allows 1 listener socket to handle connections across VRFs). The child socket becomes bound to the V
[PATCH] iproute2: Add support for VRF device
Allow user to create a vrf device and specify its table binding. Based on the iplink_vlan implementation. Signed-off-by: Shrijeet Mukherjee Signed-off-by: David Ahern --- include/linux/if_link.h | 8 + ip/Makefile | 2 +- ip/iplink.c | 2 +- ip/iplink_vrf.c | 85 + 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 ip/iplink_vrf.c diff --git a/include/linux/if_link.h b/include/linux/if_link.h index b905cf7f4948..74dedf4320b8 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -338,6 +338,14 @@ enum macvlan_macaddr_mode { #define MACVLAN_FLAG_NOPROMISC 1 +/* VRF section */ +enum { + IFLA_VRF_UNSPEC, + IFLA_VRF_TABLE, + __IFLA_VRF_MAX +}; + +#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1) /* IPVLAN section */ enum { IFLA_IPVLAN_UNSPEC, diff --git a/ip/Makefile b/ip/Makefile index 77653ecc5785..d8b38ac2e44b 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -7,7 +7,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \ iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \ -iplink_geneve.o +iplink_geneve.o iplink_vrf.o RTMONOBJ=rtmon.o diff --git a/ip/iplink.c b/ip/iplink.c index 369d50eab94e..14bf7211a447 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -94,7 +94,7 @@ void iplink_usage(void) fprintf(stderr, "TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |\n"); fprintf(stderr, " bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |\n"); fprintf(stderr, " gre | gretap | ip6gre | ip6gretap | vti | nlmon |\n"); - fprintf(stderr, " bond_slave | ipvlan | geneve }\n"); + fprintf(stderr, " bond_slave | ipvlan | geneve | vrf }\n"); } exit(-1); } diff --git a/ip/iplink_vrf.c b/ip/iplink_vrf.c new file mode 100644 index ..0d7e21c7c152 --- /dev/null +++ b/ip/iplink_vrf.c @@ -0,0 +1,85 @@ +/* iplink_vrf.cVRF device support + * + * 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. + * + * Authors: Shrijeet Mukherjee + */ + +#include +#include +#include +#include +#include + +#include "rt_names.h" +#include "utils.h" +#include "ip_common.h" + +static void vrf_explain(FILE *f) +{ + fprintf(f, "Usage: ... vrf table TABLEID \n"); +} + +static void explain(void) +{ + vrf_explain(stderr); +} + +static int table_arg(void) +{ + fprintf(stderr,"Error: argument of \"table\" must be 0-32767 and currently unused\n"); + return -1; +} + +static int vrf_parse_opt(struct link_util *lu, int argc, char **argv, + struct nlmsghdr *n) +{ + while (argc > 0) { + if (matches(*argv, "table") == 0) { + __u32 table = 0; + NEXT_ARG(); + + table = atoi(*argv); + if (table < 0 || table > 32767) + return table_arg(); + addattr32(n, 1024, IFLA_VRF_TABLE, table); + } else if (matches(*argv, "help") == 0) { + explain(); + return -1; + } else { + fprintf(stderr, "vrf: unknown option \"%s\"?\n", + *argv); + explain(); + return -1; + } + argc--, argv++; + } + + return 0; +} + +static void vrf_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) +{ + if (!tb) + return; + + if (tb[IFLA_VRF_TABLE]) + fprintf(f, "table %u ", rta_getattr_u32(tb[IFLA_VRF_TABLE])); +} + +static void vrf_print_help(struct link_util *lu, int argc, char **argv, + FILE *f) +{ + vrf_explain(f); +} + +struct link_util vrf_link_util = { + .id = "vrf", + .maxattr= IFLA_VRF_MAX, + .parse_opt = vrf_parse_opt, + .print_opt = vrf_print_opt, + .print_help = vrf_print_help, +}; -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/10] net: Use passed in table for nexthop lookups
If a user passes in a table for new routes use that table for nexthop lookups. Specifically, this solves the case where a connected route does not exist in the main table, but only another table and then a subsequent route is added with a next hop using the connected route. ie., $ ip route ls default via 10.0.2.2 dev eth0 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 169.254.0.0/16 dev eth0 scope link metric 1003 192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.51 $ ip route ls table 10 1.1.1.0/24 dev eth2 scope link Without this patch adding a nexthop route fails: $ ip route add table 10 2.2.2.0/24 via 1.1.1.10 RTNETLINK answers: Network is unreachable With this patch the route is added successfully. Signed-off-by: David Ahern --- net/ipv4/fib_semantics.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 85e9a8abf15c..b7f1d20a9615 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -691,6 +691,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, } rcu_read_lock(); { + struct fib_table *tbl = NULL; struct flowi4 fl4 = { .daddr = nh->nh_gw, .flowi4_scope = cfg->fc_scope + 1, @@ -701,8 +702,16 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, /* It is not necessary, but requires a bit of thinking */ if (fl4.flowi4_scope < RT_SCOPE_LINK) fl4.flowi4_scope = RT_SCOPE_LINK; - err = fib_lookup(net, &fl4, &res, -FIB_LOOKUP_IGNORE_LINKSTATE); + + if (cfg->fc_table) + tbl = fib_get_table(net, cfg->fc_table); + + if (tbl) + err = fib_table_lookup(tbl, &fl4, &res, + FIB_LOOKUP_IGNORE_LINKSTATE); + else + err = fib_lookup(net, &fl4, &res, +FIB_LOOKUP_IGNORE_LINKSTATE); if (err) { rcu_read_unlock(); return err; -- 2.3.2 (Apple Git-55) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
On Tue, Aug 04, 2015 at 07:12:48PM +0100, Julien Grall wrote: [...] > diff --git a/drivers/net/xen-netback/netback.c > b/drivers/net/xen-netback/netback.c > index 7d50711..3b7b7c3 100644 > --- a/drivers/net/xen-netback/netback.c > +++ b/drivers/net/xen-netback/netback.c > @@ -314,7 +314,7 @@ static void xenvif_gop_frag_copy(struct xenvif_queue > *queue, struct sk_buff *skb > } else { > copy_gop->source.domid = DOMID_SELF; > copy_gop->source.u.gmfn = > - virt_to_mfn(page_address(page)); > + virt_to_gfn(page_address(page)); > } > copy_gop->source.offset = offset; > > @@ -1284,7 +1284,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue > *queue, > queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset; > > queue->tx_copy_ops[*copy_ops].dest.u.gmfn = > - virt_to_mfn(skb->data); > + virt_to_gfn(skb->data); > queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF; > queue->tx_copy_ops[*copy_ops].dest.offset = > offset_in_page(skb->data); Acked-by: Wei Liu -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
On Wed, Aug 05, 2015 at 11:08:55AM +0100, Stefano Stabellini wrote: > On Tue, 4 Aug 2015, Julien Grall wrote: > > Based on include/xen/mm.h [1], Linux is mistakenly using MFN when GFN > > is meant, I suspect this is because the first support for Xen was for > > PV. This resulted in some misimplementation of helpers on ARM and > > confused developers about the expected behavior. > > > > For instance, with pfn_to_mfn, we expect to get an MFN based on the name. > > Although, if we look at the implementation on x86, it's returning a GFN. > > > > For clarity and avoid new confusion, replace any reference to mfn with > > gfn in any helpers used by PV drivers. The x86 code will still keep some > > reference of pfn_to_mfn but exclusively for PV (a BUG_ON has been added > > to ensure this). No changes as been made in the hypercall field, even > > though they may be invalid, in order to keep the same as the defintion > > in xen repo. > > > > Take also the opportunity to simplify simple construction such > > as pfn_to_mfn(page_to_pfn(page)) into page_to_gfn. More complex clean up > > will come in follow-up patches. > > > > [1] > > http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb > > > > Signed-off-by: Julien Grall > > Cc: Stefano Stabellini > > Cc: Russell King > > Cc: Konrad Rzeszutek Wilk > > Cc: Boris Ostrovsky > > Cc: David Vrabel > > Cc: Thomas Gleixner > > Cc: Ingo Molnar > > Cc: "H. Peter Anvin" > > Cc: x...@kernel.org > > Cc: "Roger Pau Monné" > > Cc: Dmitry Torokhov > > Cc: Ian Campbell > > Cc: Wei Liu > > Cc: Juergen Gross > > Cc: "James E.J. Bottomley" > > Cc: Greg Kroah-Hartman > > Cc: Jiri Slaby > > Cc: Jean-Christophe Plagniol-Villard > > Cc: Tomi Valkeinen > > Cc: linux-in...@vger.kernel.org > > Cc: netdev@vger.kernel.org > > Cc: linux-s...@vger.kernel.org > > Cc: linuxppc-...@lists.ozlabs.org > > Cc: linux-fb...@vger.kernel.org > > Cc: linux-arm-ker...@lists.infradead.org > > Aside from the x86 bits: > > Reviewed-by: Stefano Stabellini Not really important, but just in case anyone waits for my ack on input bits: Acked-by: Dmitry Torokhov Thanks. -- Dmitry -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sky2: Add module parameter for passing the MAC address
On Wed, 5 Aug 2015 16:50:54 +0100 Liviu Dudau wrote: > For designs where EEPROMs are not connected to PCI Yukon2 > chips we need to get the MAC address from the firmware. > Add a module parameter called 'mac_address' for this. It > will be used if no DT node can be found and the B2_MAC > register holds an invalid value. > > Signed-off-by: Liviu Dudau Yes, I can see that this can be a real problem, and other drivers solve the problem. The standard method is to assign a random mac address (and then let scripts overwrite) rather than introducing module parameter. Module parameters are discouraged because they are device specific. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next] net: Fix race condition in store_rps_map
There is a race condition in store_rps_map that allows jump label count in rps_needed to go below zero. This can happen when concurrently attempting to set and a clear map. Scenario: 1. rps_needed count is zero 2. New map is assigned by setting thread, but rps_needed count _not_ yet incremented (rps_needed count still zero) 2. Map is cleared by second thread, old_map set to that just assigned 3. Second thread performs static_key_slow_dec, rps_needed count now goes negative Fix is to increment or decrement rps_needed under the spinlock. Signed-off-by: Tom Herbert --- net/core/net-sysfs.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 194c1d0..39ec694 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -726,14 +726,17 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue, old_map = rcu_dereference_protected(queue->rps_map, lockdep_is_held(&rps_map_lock)); rcu_assign_pointer(queue->rps_map, map); - spin_unlock(&rps_map_lock); if (map) static_key_slow_inc(&rps_needed); - if (old_map) { - kfree_rcu(old_map, rcu); + if (old_map) static_key_slow_dec(&rps_needed); - } + + spin_unlock(&rps_map_lock); + + if (old_map) + kfree_rcu(old_map, rcu); + free_cpumask_var(mask); return len; } -- 1.8.5.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Xen-devel] printk from softirq on xen: hard lockup
Hi folks, I have written an extremely simple reproducer. Xen 4.5.1. Linux 4.1.3. Config attached. Reproducer attached. Makefile attached. It results in the COMPLETE lockup of the system when it receives a network packet over the Xen PV network interface. The lockup is 100% reliable. As in the messages above, it puts this -- "while (native_apic_mem_read(APIC_ICR) & APIC_ICR_BUSY)" into a busy loop that never exits. It is triggered by a simple printk in softirq. Thanks, Jason Makefile Description: Binary data #include #include #include #include #include static struct socket *s = NULL; static int receive(struct sock *sk, struct sk_buff *skb) { net_info_ratelimited("The printing of this message will crash a Xen PV guest.\n"); dev_kfree_skb(skb); return 0; } static int __init mod_init(void) { int ret; struct udp_port_cfg port = { .family = AF_INET, .local_ip = { htonl(INADDR_ANY) }, .local_udp_port = htons(32812), .use_udp_checksums = 1 }; struct udp_tunnel_sock_cfg tunnel = { .encap_type = 1, .encap_rcv = receive }; ret = udp_sock_create4(&init_net, &port, &s); if (ret) return ret; setup_udp_tunnel_sock(&init_net, s, &tunnel); return ret; } static void __exit mod_exit(void) { if (s) udp_tunnel_sock_release(s); } module_init(mod_init); module_exit(mod_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Send a UDP packet to port 32812"); MODULE_AUTHOR("Jason A. Donenfeld "); 4.1.3-domU-config Description: Binary data
Re: [PATCH v6 3/4] bpf: Implement function bpf_perf_event_read() that get the selected hardware PMU conuter
On Wed, Aug 05, 2015 at 09:08:32AM -0700, Alexei Starovoitov wrote: > On 8/5/15 6:53 AM, Peter Zijlstra wrote: > >+/* > >+ * If the event is currently on this CPU, its either a per-task event, > >+ * or local to this CPU. Furthermore it means its ACTIVE (otherwise > >+ * oncpu == -1). > >+ */ > >+if (event->oncpu == smp_processor_id()) > >+event->pmu->read(event); > >+ > >+val = local64_read(&event->count); > >+local_irq_restore(flags); > >+ > > nice! cleaner and faster. > so raw_spin_lock(&ctx->lock) is not needed, because > update_*(event) methods are not called, right? Indeed, and by ensuring the event is indeed local (by force of WARN_ON) disabling IRQs will avoid counter scheduling and result in a stable event state. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH net-next] vxlan: combine VXLAN_FLOWBASED into VXLAN_COLLECT_METADATA
On 8/5/15 7:42 AM, Thomas Graf wrote: I have no objection since a flag to enable tx only can be added again if needed. As stated in the other thread, the tx only mode which is what VXLAN was capable of doing so far is what motivated the split of flags. I see the intent. A bit confusing though, since today FLOWBASED affects pieces of TX and RX and COLLECT_METADATA another piece of RX. After the patch COLLECT_METADATA does it all. imo cleaner. but yeah, as you said, we can add 'tx only' later if really needed. thanks for review! -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH net-next] net/mlx5_core: Set log_uar_page_sz for non 4K page size architecture
From: Carol L Soto failed to configure the page size for architectures with page size different than 4K. Signed-off-by: Carol L Soto --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 603a8b0..03aabdd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -391,6 +391,8 @@ static int handle_hca_cap(struct mlx5_core_dev *dev) /* disable cmdif checksum */ MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0); + MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12); + err = set_caps(dev, set_ctx, set_sz); query_ex: -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 3/4] bpf: Implement function bpf_perf_event_read() that get the selected hardware PMU conuter
On 8/5/15 6:53 AM, Peter Zijlstra wrote: + /* +* If the event is currently on this CPU, its either a per-task event, +* or local to this CPU. Furthermore it means its ACTIVE (otherwise +* oncpu == -1). +*/ + if (event->oncpu == smp_processor_id()) + event->pmu->read(event); + + val = local64_read(&event->count); + local_irq_restore(flags); + nice! cleaner and faster. so raw_spin_lock(&ctx->lock) is not needed, because update_*(event) methods are not called, right? -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 3/4] bpf: Implement function bpf_perf_event_read() that get the selected hardware PMU conuter
On 8/5/15 3:15 AM, Peter Zijlstra wrote: On Wed, Aug 05, 2015 at 12:04:25PM +0200, Peter Zijlstra wrote: On Tue, Aug 04, 2015 at 08:58:15AM +, Kaixu Xia wrote: + event->ctx->task != current) Strictly speaking we should hold rcu_read_lock around dereferencing event->ctx (or have IRQs disabled -- although I know Paul doesn't like us relying on that). programs are always executing under rcu_read_lock, so we should be good here too. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 3/4] bpf: Implement function bpf_perf_event_read() that get the selected hardware PMU conuter
On 8/5/15 3:04 AM, Peter Zijlstra wrote: >+ __perf_event_read(event); >+ return perf_event_count(event); >+} Also, you probably want a WARN_ON(in_nmi()) there, this function is _NOT_ NMI safe. we check that very early on: unsigned int trace_call_bpf(struct bpf_prog *prog, void *ctx) { unsigned int ret; if (in_nmi()) /* not supported yet */ return 1; ... -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] sky2: Add module parameter for passing the MAC address
For designs where EEPROMs are not connected to PCI Yukon2 chips we need to get the MAC address from the firmware. Add a module parameter called 'mac_address' for this. It will be used if no DT node can be found and the B2_MAC register holds an invalid value. Signed-off-by: Liviu Dudau --- drivers/net/ethernet/marvell/sky2.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index d9f4498..a977d95 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -101,6 +101,10 @@ static int legacy_pme = 0; module_param(legacy_pme, int, 0); MODULE_PARM_DESC(legacy_pme, "Legacy power management"); +/* Ugh! Let the firmware tell us the hardware address */ +static int mac_address[ETH_ALEN] = { 0, }; +module_param_array(mac_address, int, NULL, 0); + static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ @@ -4811,13 +4815,21 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, /* try to get mac address in the following order: * 1) from device tree data * 2) from internal registers set by bootloader +* 3) from the command line parameter */ iap = of_get_mac_address(hw->pdev->dev.of_node); if (iap) memcpy(dev->dev_addr, iap, ETH_ALEN); - else + else { memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); + if (!is_valid_ether_addr(&dev->dev_addr[0])) { + int i; + + for (i = 0; i < ETH_ALEN; i++) + dev->dev_addr[i] = mac_address[i]; + } + } return dev; } -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v2 1/9] devres: add devm_alloc_percpu()
Introduce managed counterparts for alloc_percpu() and free_percpu(). Add devm_alloc_percpu() and devm_free_percpu() into the managed interfaces list. Signed-off-by: Madalin Bucur --- Documentation/driver-model/devres.txt | 4 +++ drivers/base/devres.c | 64 +++ include/linux/device.h| 19 +++ 3 files changed, 87 insertions(+) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 831a536..595fd1b 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -312,6 +312,10 @@ MEM devm_kvasprintf() devm_kzalloc() +PER-CPU MEM + devm_alloc_percpu() + devm_free_percpu() + PCI pcim_enable_device() : after success, all PCI ops become managed pcim_pin_device(): keep PCI device enabled after release diff --git a/drivers/base/devres.c b/drivers/base/devres.c index c8a53d1..deb2ea0 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "base.h" @@ -984,3 +985,66 @@ void devm_free_pages(struct device *dev, unsigned long addr) &devres)); } EXPORT_SYMBOL_GPL(devm_free_pages); + +static void devm_percpu_release(struct device *dev, void *pdata) +{ + void __percpu *p; + + p = *(void __percpu **)pdata; + free_percpu(p); +} + +static int devm_percpu_match(struct device *dev, void *data, void *p) +{ + struct devres *devr = container_of(data, struct devres, data); + + return *(void **)devr->data == p; +} + +/** + * __devm_alloc_percpu - Resource-managed alloc_percpu + * @dev: Device to allocate per-cpu memory for + * @size: Size of per-cpu memory to allocate + * @align: Alignement of per-cpu memory to allocate + * + * Managed alloc_percpu. Per-cpu memory allocated with this function is + * automatically freed on driver detach. + * + * RETURNS: + * Pointer to allocated memory on success, NULL on failure. + */ +void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, + size_t align) +{ + void *p; + void __percpu *pcpu; + + pcpu = __alloc_percpu(size, align); + if (!pcpu) + return NULL; + + p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL); + if (!p) + return NULL; + + *(void __percpu **)p = pcpu; + + devres_add(dev, p); + + return pcpu; +} +EXPORT_SYMBOL_GPL(__devm_alloc_percpu); + +/** + * devm_free_percpu - Resource-managed free_percpu + * @dev: Device this memory belongs to + * @pdata: Per-cpu memory to free + * + * Free memory allocated with devm_alloc_percpu(). + */ +void devm_free_percpu(struct device *dev, void __percpu *pdata) +{ + WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, + (void *)pdata)); +} +EXPORT_SYMBOL_GPL(devm_free_percpu); diff --git a/include/linux/device.h b/include/linux/device.h index a2b4ea7..126c25b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -673,6 +673,25 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); +/** + * devm_alloc_percpu - Resource-managed alloc_percpu + * @dev: Device to allocate per-cpu memory for + * @type: Type to allocate per-cpu memory for + * + * Managed alloc_percpu. Per-cpu memory allocated with this function is + * automatically freed on driver detach. + * + * RETURNS: + * Pointer to allocated memory on success, NULL on failure. + */ +#define devm_alloc_percpu(dev, type) \ + (typeof(type) __percpu *)__devm_alloc_percpu(dev, sizeof(type), \ +__alignof__(type)) + +void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, + size_t align); +void devm_free_percpu(struct device *dev, void __percpu *pdata); + struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v2 4/9] dpaa_eth: add driver's Tx queue selection mechanism
Allow the selection of the transmission queue based on the CPU id. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/Kconfig | 10 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth.c| 3 +++ drivers/net/ethernet/freescale/dpaa/dpaa_eth.h| 6 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c | 8 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h | 4 5 files changed, 31 insertions(+) diff --git a/drivers/net/ethernet/freescale/dpaa/Kconfig b/drivers/net/ethernet/freescale/dpaa/Kconfig index 1f3a203..6147403 100644 --- a/drivers/net/ethernet/freescale/dpaa/Kconfig +++ b/drivers/net/ethernet/freescale/dpaa/Kconfig @@ -11,6 +11,16 @@ menuconfig FSL_DPAA_ETH if FSL_DPAA_ETH +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE + bool "Use driver's Tx queue selection mechanism" + default y + ---help--- + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection + of the egress FQ. That will override the XPS support for this netdevice. + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping, + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this + and use the standard XPS support instead. + config FSL_DPAA_CS_THRESHOLD_1G hex "Egress congestion threshold on 1G ports" range 0x1000 0x1000 diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 53c37cd..264945c 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -387,6 +387,9 @@ static const struct net_device_ops dpa_private_ops = { .ndo_get_stats64 = dpa_get_stats64, .ndo_set_mac_address = dpa_set_mac_address, .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE + .ndo_select_queue = dpa_select_queue, +#endif .ndo_change_mtu = dpa_change_mtu, .ndo_set_rx_mode = dpa_set_rx_mode, .ndo_init = dpa_ndo_init, diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index d337dcc..55c1106 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -430,9 +430,15 @@ static inline void _dpa_assign_wq(struct dpa_fq *fq) } } +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE +/* Use in lieu of skb_get_queue_mapping() */ +#define dpa_get_queue_mapping(skb) \ + raw_smp_processor_id() +#else /* Use the queue selected by XPS */ #define dpa_get_queue_mapping(skb) \ skb_get_queue_mapping(skb) +#endif static inline void _dpa_bp_free_pf(void *addr) { diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c index 7e4b9bd..1258683 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c @@ -586,6 +586,14 @@ bool dpa_bpid2pool_use(int bpid) return false; } +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb, +void *accel_priv, select_queue_fallback_t fallback) +{ + return dpa_get_queue_mapping(skb); +} +#endif + struct dpa_fq *dpa_fq_alloc(struct device *dev, const struct fqid_cell *fqids, struct list_head *list, diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h index bd88dda..4581bfc 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h @@ -88,6 +88,10 @@ struct dpa_bp *dpa_bpid2pool(int bpid); void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp); bool dpa_bpid2pool_use(int bpid); void dpa_bp_drain(struct dpa_bp *bp); +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb, +void *accel_priv, select_queue_fallback_t fallback); +#endif struct dpa_fq *dpa_fq_alloc(struct device *dev, const struct fqid_cell *fqids, struct list_head *list, -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v2 3/9] dpaa_eth: add support for S/G frames
Add support for Scater/Gather (S/G) frames. The FMan can place the frame content into multiple buffers and provide a S/G Table (SGT) into one first buffer with references to the others. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 6 + .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 47 ++- .../net/ethernet/freescale/dpaa/dpaa_eth_common.h | 2 + drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c | 335 +++-- 4 files changed, 370 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 9e83bd1..53c37cd 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -460,6 +460,12 @@ static int dpa_private_netdev_init(struct net_device *net_dev) net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_LLTX); + /* Advertise S/G and HIGHDMA support for private interfaces */ + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA; + /* Recent kernels enable GSO automatically, if +* we declare NETIF_F_SG. For conformity, we'll +* still declare GSO explicitly. +*/ net_dev->features |= NETIF_F_GSO; return dpa_netdev_init(net_dev, mac_addr, tx_timeout); diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c index 10f08f7..7e4b9bd 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c @@ -1122,6 +1122,35 @@ void dpaa_eth_init_ports(struct mac_device *mac_dev, port_fqs->rx_defq, &buf_layout[RX]); } +void dpa_release_sgt(struct qm_sg_entry *sgt) +{ + struct dpa_bp *dpa_bp; + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX]; + u8 i = 0, j; + + memset(bmb, 0, sizeof(bmb)); + + do { + dpa_bp = dpa_bpid2pool(sgt[i].bpid); + DPA_ERR_ON(!dpa_bp); + + j = 0; + do { + DPA_ERR_ON(sgt[i].extension); + + bmb[j].hi = sgt[i].addr_hi; + bmb[j].lo = sgt[i].addr_lo; + + j++; i++; + } while (j < ARRAY_SIZE(bmb) && + !sgt[i - 1].final && + sgt[i - 1].bpid == sgt[i].bpid); + + while (bman_release(dpa_bp->pool, bmb, j, 0)) + cpu_relax(); + } while (!sgt[i - 1].final); +} + void __attribute__((nonnull)) dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd) { @@ -1137,7 +1166,23 @@ dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd) dpa_bp = dpa_bpid2pool(fd->bpid); DPA_ERR_ON(!dpa_bp); - DPA_ERR_ON(fd->format == qm_fd_sg); + if (fd->format == qm_fd_sg) { + vaddr = phys_to_virt(fd->addr); + sgt = vaddr + dpa_fd_offset(fd); + + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size, +DMA_BIDIRECTIONAL); + + dpa_release_sgt(sgt); + + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(dpa_bp->dev, addr)) { + dev_err(dpa_bp->dev, "DMA mapping failed"); + return; + } + bm_buffer_set64(&bmb, addr); + } while (bman_release(dpa_bp->pool, &bmb, 1, 0)) cpu_relax(); diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h index 93fcf82..bd88dda 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h @@ -52,6 +52,7 @@ fm_set_##type##_port_params(port, ¶m); \ } +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */ #define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */ /* used in napi related functions */ @@ -109,6 +110,7 @@ void dpaa_eth_init_ports(struct mac_device *mac_dev, struct fm_port_fqs *port_fqs, struct dpa_buffer_layout_s *buf_layout, struct device *dev); +void dpa_release_sgt(struct qm_sg_entry *sgt); void __attribute__((nonnull)) dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd); int dpa_enable_tx_csum(struct dpa_priv_s *priv, diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c index 15713a6..6050448 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c @@ -53,6 +53,31 @@
[v2 0/9] dpaa_eth: Add the Freescale DPAA Ethernet driver
This patch series adds the Ethernet driver for the Freescale QorIQ Data Path Acceleration Architecture (DPAA). This version includes changes following the feedback received on previous versions from Eric Dumazet, Bob Cochran, Joe Perches, Paul Bolle, Joakim Tjernlund, Scott Wood, David Miller - thanks! Together with the driver a managed version of alloc_percpu is provided that simplifies the release of percpu memory. The Freescale DPAA architecture consists in a series of hardware blocks that support the Ethernet connectivity. The Ethernet driver depends upon the following drivers that are currently in the Linux kernel or in review: - Peripheral Access Memory Unit (PAMU) drivers/iommu/fsl_* - Frame Manager (FMan) drivers/net/ethernet/freescale/fman - Queue Manager (QMan), Buffer Manager (BMan) drivers/soc/fsl/qbman The latest FMan driver patches were submitted by Igal Liberman: https://patchwork.ozlabs.org/project/netdev/list/?submitter=64715&state=*&q=[v4, The latest Q/BMan drivers were submitted by Roy Pledge: https://patchwork.ozlabs.org/project/linuxppc-dev/list/?submitter=66331&state=* Changes from v1: - bpool level Kconfig options removed - print format using pr_fmt, cleaned up prints - __hot/__cold removed - gratuitous unlikely() removed - code style aligned, consistent spacing for declarations - comment formatting The complete patch set based on the v4.2-rc5 kernel can be found in the public git http://git.freescale.com/git/cgit.cgi/ppc/upstream/linux.git under the tag ldup_public_git_20150805: http://git.freescale.com/git/cgit.cgi/ppc/upstream/linux.git/log/?h=ldup_public_git_20150805 There is one patch that needs to be applied to u-boot to align it to the latest device tree binding document specification used by the FMan driver. The patch is under the ldup_public_git_20150410 tag in the public git at: http://git.freescale.com/git/cgit.cgi/ppc/upstream/u-boot.git/log/?h=ldup_public_git_20150410 Madalin Bucur (9): devres: add devm_alloc_percpu() dpaa_eth: add support for DPAA Ethernet dpaa_eth: add support for S/G frames dpaa_eth: add driver's Tx queue selection mechanism dpaa_eth: add ethtool functionality dpaa_eth: add sysfs exports dpaa_eth: add debugfs counters dpaa_eth: add debugfs entries dpaa_eth: add trace points Documentation/driver-model/devres.txt |4 + drivers/base/devres.c | 64 + drivers/net/ethernet/freescale/Kconfig |2 + drivers/net/ethernet/freescale/Makefile|1 + drivers/net/ethernet/freescale/dpaa/Kconfig| 63 + drivers/net/ethernet/freescale/dpaa/Makefile | 17 + drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c | 272 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h | 43 + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 860 + drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 489 +++ .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 1358 .../net/ethernet/freescale/dpaa/dpaa_eth_common.h | 129 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c | 704 ++ .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c | 167 +++ .../net/ethernet/freescale/dpaa/dpaa_eth_trace.h | 141 ++ drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 230 include/linux/device.h | 19 + 17 files changed, 4563 insertions(+) create mode 100644 drivers/net/ethernet/freescale/dpaa/Kconfig create mode 100644 drivers/net/ethernet/freescale/dpaa/Makefile create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v2 8/9] dpaa_eth: add debugfs entries
Export per CPU counters through debugfs. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/Kconfig| 7 + drivers/net/ethernet/freescale/dpaa/Makefile | 3 + drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c | 272 + drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h | 43 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 11 + .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 17 ++ 6 files changed, 353 insertions(+) create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h diff --git a/drivers/net/ethernet/freescale/dpaa/Kconfig b/drivers/net/ethernet/freescale/dpaa/Kconfig index 6147403..98c6328 100644 --- a/drivers/net/ethernet/freescale/dpaa/Kconfig +++ b/drivers/net/ethernet/freescale/dpaa/Kconfig @@ -53,4 +53,11 @@ config FSL_DPAA_INGRESS_CS_THRESHOLD The size in bytes of the ingress tail-drop threshold on FMan ports. Traffic piling up above this value will be rejected by QMan and discarded by FMan. +config FSL_DPAA_ETH_DEBUGFS + bool "DPAA Ethernet debugfs interface" + depends on DEBUG_FS + default y + ---help--- + This option compiles debugfs code for the DPAA Ethernet driver. + endif # FSL_DPAA_ETH diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile b/drivers/net/ethernet/freescale/dpaa/Makefile index 3a276d5..3427de4 100644 --- a/drivers/net/ethernet/freescale/dpaa/Makefile +++ b/drivers/net/ethernet/freescale/dpaa/Makefile @@ -11,3 +11,6 @@ ccflags-y += -I$(FMAN)/flib obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o dpaa_eth_sysfs.o +ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y) +fsl_dpa-objs += dpaa_debugfs.o +endif diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c b/drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c new file mode 100644 index 000..bd426f0 --- /dev/null +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c @@ -0,0 +1,272 @@ +/* Copyright 2008 - 2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include "dpaa_debugfs.h" +#include "dpaa_eth.h" + +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries" +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa" + +static int dpa_debugfs_open(struct inode *inode, struct file *file); + +static struct dentry *dpa_debugfs_root; +static const struct file_operations dpa_debugfs_fops = { + .open = dpa_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + +static int dpa_debugfs_show(struct seq_file *file, void *offset) +{ + int i; + struct dpa_priv_s *priv; + struct dpa_percpu_priv_s *percpu_priv, total; + struct dpa_bp *dpa_bp; + unsigned int dpa_bp_count = 0; + unsigned int count_total = 0; + struct qm_mcr_querycgr query_cgr; + + BUG_ON(!offset); + + priv = netdev_priv((struct net_device *)file->private); + + dpa_bp = priv->dpa_bp; + + memset(&total, 0, sizeof(tota
[v2 6/9] dpaa_eth: add sysfs exports
Export Frame Queue and Buffer Pool IDs through sysfs. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/Makefile | 2 +- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 + drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 3 + .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 2 + .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c | 167 + 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile b/drivers/net/ethernet/freescale/dpaa/Makefile index e137146..3a276d5 100644 --- a/drivers/net/ethernet/freescale/dpaa/Makefile +++ b/drivers/net/ethernet/freescale/dpaa/Makefile @@ -10,4 +10,4 @@ ccflags-y += -I$(FMAN)/flib obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o -fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o +fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o dpaa_eth_sysfs.o diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 264945c..a1183f4 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -739,6 +739,8 @@ dpaa_eth_priv_probe(struct platform_device *pdev) if (err < 0) goto netdev_init_failed; + dpaa_eth_sysfs_init(&net_dev->dev); + pr_info("Probed interface %s\n", net_dev->name); return 0; diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index 55c1106..2a0ecf3 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -344,6 +344,9 @@ static inline u16 dpa_get_headroom(struct dpa_buffer_layout_s *bl) return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom; } +void dpaa_eth_sysfs_remove(struct device *dev); +void dpaa_eth_sysfs_init(struct device *dev); + void dpa_private_napi_del(struct net_device *net_dev); static inline void clear_fd(struct qm_fd *fd) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c index ca6831a..1e43fe5 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c @@ -279,6 +279,8 @@ int dpa_remove(struct platform_device *pdev) priv = netdev_priv(net_dev); + dpaa_eth_sysfs_remove(dev); + dev_set_drvdata(dev, NULL); unregister_netdev(net_dev); diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c new file mode 100644 index 000..a6c71b1 --- /dev/null +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c @@ -0,0 +1,167 @@ +/* Copyright 2008-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include "dpaa_eth.h" +#include "mac.h" + +static ssize_t dpaa_eth_show_addr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dpa_priv_s *priv =
[v2 7/9] dpaa_eth: add debugfs counters
Add a series of counters to be exported through debugfs: - add detailed counters for reception errors; - add detailed counters for QMan enqueue reject events; - count the number of fragmented skbs received from the stack; - count all frames received on the Tx confirmation path; - add congestion group statistics; - count the number of interrupts for each CPU. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 12 +++ drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 34 ++ .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 40 -- .../net/ethernet/freescale/dpaa/dpaa_eth_common.h | 2 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c | 1 + 5 files changed, 87 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index a1183f4..008562b 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -98,6 +98,15 @@ static void _dpa_rx_error(struct net_device *net_dev, percpu_priv->stats.rx_errors++; + if (fd->status & FM_PORT_FRM_ERR_DMA) + percpu_priv->rx_errors.dme++; + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL) + percpu_priv->rx_errors.fpe++; + if (fd->status & FM_PORT_FRM_ERR_SIZE) + percpu_priv->rx_errors.fse++; + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR) + percpu_priv->rx_errors.phe++; + dpa_fd_release(net_dev, fd); } @@ -161,6 +170,8 @@ static void _dpa_tx_conf(struct net_device *net_dev, percpu_priv->stats.tx_errors++; } + percpu_priv->tx_confirm++; + skb = _dpa_cleanup_tx_fd(priv, fd); dev_kfree_skb(skb); @@ -296,6 +307,7 @@ static void priv_ern(struct qman_portal *portal, percpu_priv->stats.tx_dropped++; percpu_priv->stats.tx_fifo_errors++; + count_ern(percpu_priv, msg); /* If we intended this buffer to go into the pool * when the FM was done, we need to put it in diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index 2a0ecf3..c66140e 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -194,6 +194,25 @@ struct dpa_bp { void (*free_buf_cb)(void *addr); }; +struct dpa_rx_errors { + u64 dme;/* DMA Error */ + u64 fpe;/* Frame Physical Error */ + u64 fse;/* Frame Size Error */ + u64 phe;/* Header Error */ +}; + +/* Counters for QMan ERN frames - one counter per rejection code */ +struct dpa_ern_cnt { + u64 cg_tdrop; /* Congestion group taildrop */ + u64 wred; /* WRED congestion */ + u64 err_cond; /* Error condition */ + u64 early_window; /* Order restoration, frame too early */ + u64 late_window;/* Order restoration, frame too late */ + u64 fq_tdrop; /* FQ taildrop */ + u64 fq_retired; /* FQ is retired */ + u64 orp_zero; /* ORP disabled */ +}; + struct dpa_napi_portal { struct napi_struct napi; struct qman_portal *p; @@ -202,7 +221,13 @@ struct dpa_napi_portal { struct dpa_percpu_priv_s { struct net_device *net_dev; struct dpa_napi_portal *np; + u64 in_interrupt; + u64 tx_confirm; + /* fragmented (non-linear) skbuffs received from the stack */ + u64 tx_frag_skbuffs; struct rtnl_link_stats64 stats; + struct dpa_rx_errors rx_errors; + struct dpa_ern_cnt ern_cnt; }; struct dpa_priv_s { @@ -233,6 +258,14 @@ struct dpa_priv_s { * (and the same) congestion group. */ struct qman_cgr cgr; + /* If congested, when it began. Used for performance stats. */ + u32 congestion_start_jiffies; + /* Number of jiffies the Tx port was congested. */ + u32 congested_jiffies; + /* Counter for the number of times the CGR +* entered congestion state +*/ + u32 cgr_congested_count; } cgr_data; /* Use a per-port CGR for ingress traffic. */ bool use_ingress_cgr; @@ -294,6 +327,7 @@ static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv, np->p = portal; napi_schedule(&np->napi); + percpu_priv->in_interrupt++; return 1; } } diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c index 1e43fe5..459132b 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c +++ b/drivers/net/ethernet/free
[v2 5/9] dpaa_eth: add ethtool functionality
Add support for basic ethtool operations. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/Makefile | 2 +- .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 2 + .../net/ethernet/freescale/dpaa/dpaa_eth_common.h | 3 + drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 230 + 4 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile b/drivers/net/ethernet/freescale/dpaa/Makefile index cf126dd..e137146 100644 --- a/drivers/net/ethernet/freescale/dpaa/Makefile +++ b/drivers/net/ethernet/freescale/dpaa/Makefile @@ -10,4 +10,4 @@ ccflags-y += -I$(FMAN)/flib obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o -fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o +fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c index 1258683..ca6831a 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c @@ -81,6 +81,8 @@ int dpa_netdev_init(struct net_device *net_dev, memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len); memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len); + net_dev->ethtool_ops = &dpa_ethtool_ops; + net_dev->needed_headroom = priv->tx_headroom; net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout); diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h index 4581bfc..a940561 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h @@ -58,6 +58,9 @@ /* used in napi related functions */ extern u16 qman_portal_max; +/* from dpa_ethtool.c */ +extern const struct ethtool_ops dpa_ethtool_ops; + int dpa_netdev_init(struct net_device *net_dev, const u8 *mac_addr, u16 tx_timeout); diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c new file mode 100644 index 000..069fcf1 --- /dev/null +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c @@ -0,0 +1,230 @@ +/* Copyright 2008-2015 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include + +#include "dpaa_eth.h" +#include "mac.h" +#include "dpaa_eth_common.h" + +static int dpa_get_settings(struct net_device *net_dev, + struct ethtool_cmd *et_cmd) +{ + int err; + struct dpa_priv_s *priv; + + priv = netdev_priv(net_dev); + + if (!priv->mac_dev->phy_dev) { + netdev_dbg(net_dev, "phy device not initialized\n"); + return 0; + } + + err = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd); + + return err; +} + +static int dpa_set_settings(struct net_device *net_dev, + struct ethtool_cmd *et_cmd) +{ + int err; + struct dpa_priv_s *priv; + + priv = netdev_priv(net_dev); +
[v2 2/9] dpaa_eth: add support for DPAA Ethernet
This introduces the Freescale Data Path Acceleration Architecture (DPAA) Ethernet driver (dpaa_eth) that builds upon the DPAA QMan, BMan, PAMU and FMan drivers to deliver Ethernet connectivity on the Freescale DPAA QorIQ platforms. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/Kconfig |2 + drivers/net/ethernet/freescale/Makefile|1 + drivers/net/ethernet/freescale/dpaa/Kconfig| 46 + drivers/net/ethernet/freescale/dpaa/Makefile | 13 + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 814 + drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 442 +++ .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 1248 .../net/ethernet/freescale/dpaa/dpaa_eth_common.h | 118 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c | 406 +++ 9 files changed, 3090 insertions(+) create mode 100644 drivers/net/ethernet/freescale/dpaa/Kconfig create mode 100644 drivers/net/ethernet/freescale/dpaa/Makefile create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index f3f89cc..92198be 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig @@ -92,4 +92,6 @@ config GIANFAR and MPC86xx family of chips, the eTSEC on LS1021A and the FEC on the 8540. +source "drivers/net/ethernet/freescale/dpaa/Kconfig" + endif # NET_VENDOR_FREESCALE diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile index 4097c58..ae13dc5 100644 --- a/drivers/net/ethernet/freescale/Makefile +++ b/drivers/net/ethernet/freescale/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_FS_ENET) += fs_enet/ obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o obj-$(CONFIG_FSL_XGMAC_MDIO) += xgmac_mdio.o obj-$(CONFIG_GIANFAR) += gianfar_driver.o +obj-$(CONFIG_FSL_DPAA_ETH) += dpaa/ obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o gianfar_driver-objs := gianfar.o \ gianfar_ethtool.o diff --git a/drivers/net/ethernet/freescale/dpaa/Kconfig b/drivers/net/ethernet/freescale/dpaa/Kconfig new file mode 100644 index 000..1f3a203 --- /dev/null +++ b/drivers/net/ethernet/freescale/dpaa/Kconfig @@ -0,0 +1,46 @@ +menuconfig FSL_DPAA_ETH + tristate "DPAA Ethernet" + depends on FSL_SOC && FSL_BMAN && FSL_QMAN && FSL_FMAN + select PHYLIB + select FSL_FMAN_MAC + ---help--- + Data Path Acceleration Architecture Ethernet driver, + supporting the Freescale QorIQ chips. + Depends on Freescale Buffer Manager and Queue Manager + driver and Frame Manager Driver. + +if FSL_DPAA_ETH + +config FSL_DPAA_CS_THRESHOLD_1G + hex "Egress congestion threshold on 1G ports" + range 0x1000 0x1000 + default "0x0600" + ---help--- + The size in bytes of the egress Congestion State notification threshold on 1G ports. + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop + (e.g. by sending UDP datagrams at "while(1) speed"), + and the larger the frame size, the more acute the problem. + So we have to find a balance between these factors: + - avoiding the device staying congested for a prolonged time (risking + the netdev watchdog to fire - see also the tx_timeout module param); + - affecting performance of protocols such as TCP, which otherwise +behave well under the congestion notification mechanism; + - preventing the Tx cores from tightly-looping (as if the congestion +threshold was too low to be effective); + - running out of memory if the CS threshold is set too high. + +config FSL_DPAA_CS_THRESHOLD_10G + hex "Egress congestion threshold on 10G ports" + range 0x1000 0x2000 + default "0x1000" + ---help --- + The size in bytes of the egress Congestion State notification threshold on 10G ports. + +config FSL_DPAA_INGRESS_CS_THRESHOLD + hex "Ingress congestion threshold on FMan ports" + default "0x1000" + ---help--- + The size in bytes of the ingress tail-drop threshold on FMan ports. + Traffic piling up above this value will be rejected by QMan and discarded by FMan. + +endif # FSL_DPAA_ETH diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile b/drivers/net/ethernet/freescale/dpaa/Makefile new file mode 100644 index 000..cf126dd --- /dev/null +++ b/drivers/net/ethernet/freescale/dpaa/Makefile @@ -0,0 +1,13 @@ +# +# Makefile for the Freescale
[v2 9/9] dpaa_eth: add trace points
Add trace points on the hot processing path. Signed-off-by: Ruxandra Ioana Radulescu --- drivers/net/ethernet/freescale/dpaa/Makefile | 1 + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 12 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 4 + .../net/ethernet/freescale/dpaa/dpaa_eth_trace.h | 141 + 4 files changed, 158 insertions(+) create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile b/drivers/net/ethernet/freescale/dpaa/Makefile index 3427de4..bf7248a 100644 --- a/drivers/net/ethernet/freescale/dpaa/Makefile +++ b/drivers/net/ethernet/freescale/dpaa/Makefile @@ -11,6 +11,7 @@ ccflags-y += -I$(FMAN)/flib obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o dpaa_eth_sysfs.o +CFLAGS_dpaa_eth.o := -I$(src) ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y) fsl_dpa-objs += dpaa_debugfs.o endif diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index ea25bf1..7f2413b 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -61,6 +61,12 @@ #include "dpaa_debugfs.h" #endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */ +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files + * using trace events only need to #include + */ +#define CREATE_TRACE_POINTS +#include "dpaa_eth_trace.h" + #define DPA_NAPI_WEIGHT64 /* Valid checksum indication */ @@ -226,6 +232,9 @@ priv_rx_default_dqrr(struct qman_portal *portal, priv = netdev_priv(net_dev); dpa_bp = priv->dpa_bp; + /* Trace the Rx fd */ + trace_dpa_rx_fd(net_dev, fq, &dq->fd); + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */ percpu_priv = raw_cpu_ptr(priv->percpu_priv); count_ptr = raw_cpu_ptr(dpa_bp->percpu_count); @@ -282,6 +291,9 @@ priv_tx_conf_default_dqrr(struct qman_portal *portal, net_dev = ((struct dpa_fq *)fq)->net_dev; priv = netdev_priv(net_dev); + /* Trace the fd */ + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd); + /* Non-migratable context, safe to use raw_cpu_ptr */ percpu_priv = raw_cpu_ptr(priv->percpu_priv); diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index c66140e..4ac917a 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -36,6 +36,7 @@ #include "fm_ext.h" #include "mac.h" +#include "dpaa_eth_trace.h" extern int dpa_rx_extra_headroom; extern int dpa_max_frm; @@ -417,6 +418,9 @@ static inline int dpa_xmit(struct dpa_priv_s *priv, _dpa_get_tx_conf_queue(priv, egress_fq) ); + /* Trace this Tx fd */ + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd); + for (i = 0; i < 10; i++) { err = qman_enqueue(egress_fq, fd, 0); if (err != -EBUSY) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h new file mode 100644 index 000..3b67477 --- /dev/null +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h @@ -0,0 +1,141 @@ +/* Copyright 2013-2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +
[PATCH net-next] r8169:Issues on alloc memory
Many, many issues DESC_ARRAY represent number of descriptor on array on Tx and Rx and is fit with TxDesc and RxDesc structure, MAX_DESCRIPTORS is 1024 on Rx and Tx wich is included 256 Descriptors from chip on Rx and Tx. DESC_ARRAY * NUM_ARRAYS_MAX must fit with MAX_DESCRIPTORS 256 from chip and rest from memory. DESC_ARRAY * NUM_ARRAY_MIN is hardware descriptors from chip. On doc RTL 8101/8102 and RTL 8169 report same number of descriptors 1024. Signed-off-by: Corcodel Marian diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index bf78f94..8bf8c3f 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -74,7 +74,7 @@ (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) #define TX_SLOTS_AVAIL(tp) \ - (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx) + (tp->dirty_tx + NUM_ARRAYS_MAX - tp->cur_tx) /* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ #define TX_FRAGS_READY_FOR(tp,nr_frags) \ @@ -87,13 +87,17 @@ static const int multicast_filter_limit = 32; #define MAX_READ_REQUEST_SHIFT 12 #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ #define InterFrameGap 0x03/* 3 means InterFrameGap = the shortest one */ +#define DESC_ARRAY 16 /* Number of descriptors on array to Rx and Tx */ +#define NUM_ARRAYS_MAX 64 /* Number of arrays descriptors maximum on Rx and Tx */ +#define NUM_ARRAYS_MIN 16 /* Number of arrays descriptors minimum on Rx and Tx */ +#define MAX_DESCRIPTORS1024/* Number of descriptors total and maximum on Rx and Tx */ #define R8169_REGS_SIZE256 #define R8169_NAPI_WEIGHT 64 #define NUM_TX_DESC64 /* Number of Tx descriptor registers */ #define NUM_RX_DESC256U/* Number of Rx descriptor registers */ -#define R8169_TX_RING_BYTES(NUM_TX_DESC * sizeof(struct TxDesc)) -#define R8169_RX_RING_BYTES(NUM_RX_DESC * sizeof(struct RxDesc)) +#define R8169_TX_RING_BYTES(NUM_ARRAYS_MAX * sizeof(struct TxDesc)) /* here sizeof not reporting correct */ +#define R8169_RX_RING_BYTES(NUM_ARRAYS_MAX * sizeof(struct RxDesc)) /* here sizeof not reporting correct */ #define RTL8169_TX_TIMEOUT (6*HZ) #define RTL8169_PHY_TIMEOUT(10*HZ) @@ -778,8 +782,8 @@ struct rtl8169_private { struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ dma_addr_t TxPhyAddr; dma_addr_t RxPhyAddr; - void *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */ - struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ + void *Rx_databuff[NUM_ARRAYS_MAX]; /* Rx data buffers */ + struct ring_info tx_skb[NUM_ARRAYS_MAX];/* Tx data buffers */ struct timer_list timer; u16 cp_cmd; @@ -6679,7 +6683,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) { unsigned int i; - for (i = 0; i < NUM_RX_DESC; i++) { + for (i = 0; i < NUM_ARRAYS_MAX; i++) { if (tp->Rx_databuff[i]) { rtl8169_free_rx_databuff(tp, tp->Rx_databuff + i, tp->RxDescArray + i); @@ -6696,7 +6700,7 @@ static int rtl8169_rx_fill(struct rtl8169_private *tp) { unsigned int i; - for (i = 0; i < NUM_RX_DESC; i++) { + for (i = 0; i < NUM_ARRAYS_MAX; i++) { void *data; if (tp->Rx_databuff[i]) @@ -6710,7 +6714,7 @@ static int rtl8169_rx_fill(struct rtl8169_private *tp) tp->Rx_databuff[i] = data; } - rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); + rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_ARRAYS_MAX - 1); return 0; err_out: @@ -6724,8 +6728,8 @@ static int rtl8169_init_ring(struct net_device *dev) rtl8169_init_ring_indexes(tp); - memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); - memset(tp->Rx_databuff, 0x0, NUM_RX_DESC * sizeof(void *)); + memset(tp->tx_skb, 0x0, DESC_ARRAY * NUM_ARRAYS_MIN); + memset(tp->Rx_databuff, 0x0, DESC_ARRAY * NUM_ARRAYS_MIN); return rtl8169_rx_fill(tp); } @@ -6749,7 +6753,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, unsigned int i; for (i = 0; i < n; i++) { - unsigned int entry = (start + i) % NUM_TX_DESC; + unsigned int entry = (start + i) % NUM_ARRAYS_MAX; struct ring_info *tx_skb = tp->tx_skb + entry; unsigned int len = tx_skb->len; @@ -6769,7 +6773,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, static void rtl8169_tx_clear(struct rtl8169_private *tp) { - rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); + rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_ARRAYS_MAX); tp->cur_tx = tp->dirty_tx = 0; } @@ -6784,7
Re: [PATCH] ARCNET: fix hard_header_len limit
On Thu, Jul 30, 2015 at 11:16:36AM -0700, David Miller wrote: > From: Michael Grzeschik > Date: Thu, 30 Jul 2015 15:34:36 +0200 > > > The commit <9c7077622dd9> ("packet: make packet_snd fail on len smaller > > than l2 header") adds the check for minimum packet length of the used l2. > > For arcnet the hardware header length is not the complete archdr which > > includes hard + soft header. This patch changes the length to > > sizeof(arc_hardware). > > > > Signed-off-by: Michael Grzeschik > > The hard header len is used for other purposes as well, are you sure > those don't get broken by this change? Its meaning is to represent the amount of the hardware (link layer) data of one packet. Which other purposes do you mean? Can you point to some code? > Code assumes that if the data at the SKB mac pointer is taken, for > dev->hard_header_len bytes, that is exactly the link layer header. > And that this can be used to compare two MAC headers, copy the > MAC header from one packet to another, etc. The link layer size of arcnet is 4 bytes long. 1 byte source, 1 byte dest and two offset bytes. As described by struct arc_hardware in if_arcnet.h . The above condition is fulfilled when the mac pointer is 0. The following pending bytes of struct archdr have a variable meaning depending of the used protocol and are represented by an union. (network layer) In the case of raw packets, the payload comes immediately after the hard_header. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: veths often slow to come up
On Tue, Aug 04, 2015 at 08:26:28PM -0700, Cong Wang wrote: > (Cc'ing netdev for network issues) > > On Tue, Aug 4, 2015 at 6:42 AM, Shaun Crampton > wrote: > > Please CC me on any responses, thanks. > > > > Setting both ends of a veth to be oper UP completes very quickly but I > > find that pings only start flowing over the veth after about a second. > > This seems to correlate with the NO-CARRIER flag being set or the > > interface being in "state UNKNOWN" or "state DOWN² for about a second > > (demo script below). > > > > If I run the script repeatedly then sometimes it completes very quickly on > > subsequent runs as if there¹s a hot cache somewhere. > > > > Could this be a bug or is there a configuration to speed this up? Seems > > odd that it¹s almost exactly 1s on the first run. > > > > Seen on these kernels: > > * 3.13.0-57-generic #95-Ubuntu SMP Fri Jun 19 09:28:15 UTC 2015 x86_64 > > x86_64 x86_64 GNU/Linux > > * 4.0.9-coreos #2 SMP Thu Jul 30 01:07:55 UTC 2015 x86_64 Intel(R) Xeon(R) > > CPU @ 2.50GHz GenuineIntel GNU/Linux > > > > Regards, > > > > -Shaun > > Take a look at linkwatch_urgent_event at net/core/link_watch.c, and all of link_watch.c in general. That's where the 1s delay comes from. It's designed to prevent link message storms. In particular, look at commit 294cc44b7e48a6e7732499eebcf409b231460d8e, which added the urgent event. I suspect this was designed to workaround buggy drivers/hardware, not to help userspace handle thousands of virtual devices being created and destroyed all the time. Maybe virtual devices should be whitelisted here? Maybe the patch below is stupid, because drivers may abuse it, and drivers are buggy, otherwise linkwatch would not be needed in the first place. Regards. Cascardo. > > > > Running my test script below (Assumes veth0/1 do not already exist): > > > > $ sudo ./veth-test.sh > > Time to create veth: > > > > real0m0.019s > > user0m0.002s > > sys 0m0.010s > > > > Time to wait for carrier: > > > > real0m1.005s > > user0m0.007s > > sys 0m0.123s > > > > > > > > # veth-test.sh > > > > #!/bin/bash > > function create_veth { > > ip link add type veth > > ip link set veth0 up > > ip link set veth1 up > > } > > function wait_for_carrier { > > while ! ip link show | grep -qE 'veth[01]'; > > do > > sleep 0.05 > > done > > while ip link show | grep -E 'veth[01]¹ | \ > > grep -Eq 'NO-CARRIER|state DOWN|state UNKNOWN'; > > do > > sleep 0.05 > > done > > } > > echo "Time to create veth:" > > time create_veth > > echo > > echo "Time to wait for carrier:" > > time wait_for_carrier > > ip link del veth0 --- diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 343592c..91123a8 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -306,6 +306,7 @@ static void veth_setup(struct net_device *dev) dev->priv_flags &= ~IFF_TX_SKB_SHARING; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + dev->priv_flags |= IFF_LINKWATCH_URGENT; dev->netdev_ops = &veth_netdev_ops; dev->ethtool_ops = &veth_ethtool_ops; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 607b5f4..138f5e9 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1262,6 +1262,7 @@ struct net_device_ops { * @IFF_LIVE_ADDR_CHANGE: device supports hardware address * change when it's running * @IFF_MACVLAN: Macvlan device + * @IFF_LINKWATCH_URGENT: device does not flood with link updates */ enum netdev_priv_flags { IFF_802_1Q_VLAN = 1<<0, @@ -1289,6 +1290,7 @@ enum netdev_priv_flags { IFF_XMIT_DST_RELEASE_PERM = 1<<22, IFF_IPVLAN_MASTER = 1<<23, IFF_IPVLAN_SLAVE= 1<<24, + IFF_LINKWATCH_URGENT= 1<<25, }; #define IFF_802_1Q_VLANIFF_802_1Q_VLAN diff --git a/net/core/link_watch.c b/net/core/link_watch.c index 9828616..e2957a0 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c @@ -95,6 +95,9 @@ static bool linkwatch_urgent_event(struct net_device *dev) if (dev->priv_flags & IFF_TEAM_PORT) return true; + if (dev->priv_flags & IFF_LINKWATCH_URGENT) + return true; + return netif_carrier_ok(dev) && qdisc_tx_changing(dev); } --- -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] of: fsl/fman: reuse the fixed node parsing code
The FMan MAC configuration code needs the speed and duplex information for fixed-link interfaces that is parsed now by the of function of_phy_register_fixed_link(). This parses the fixed-link parameters but does not expose to the caller neither the phy_device pointer nor the status struct where it loads the fixed-link params. By extracting the fixed-link parsing code from of_phy_register_fixed_link() into a separate function the parsed values are made available without changing the existing API. This change also removes a small redundancy in the previous code calling fixed_phy_register(). The FMan patch relies on the latest FMan driver v4 submission by Igal Liberman: https://patchwork.ozlabs.org/project/netdev/list/?submitter=Igal.Liberman&state=*&q=v4 Madalin Bucur (2): of: separate fixed link parsing from registration fsl_fman: use fixed_phy_status for MEMAC .../ethernet/freescale/fman/flib/fsl_fman_memac.h | 6 ++- drivers/net/ethernet/freescale/fman/inc/mac.h | 2 +- drivers/net/ethernet/freescale/fman/mac/fm_memac.c | 42 - drivers/net/ethernet/freescale/fman/mac/fm_memac.h | 3 +- drivers/net/ethernet/freescale/fman/mac/mac.c | 18 ++-- drivers/of/of_mdio.c | 52 ++ include/linux/of_mdio.h| 9 7 files changed, 94 insertions(+), 38 deletions(-) -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 2/2] fsl_fman: use fixed_phy_status for MEMAC
Use the speed and duplex information from the device tree fixed link node accessing the status structure parsed by of_phy_parse_fixed_link(). Signed-off-by: Madalin Bucur --- .../ethernet/freescale/fman/flib/fsl_fman_memac.h | 6 ++-- drivers/net/ethernet/freescale/fman/inc/mac.h | 2 +- drivers/net/ethernet/freescale/fman/mac/fm_memac.c | 42 -- drivers/net/ethernet/freescale/fman/mac/fm_memac.h | 3 +- drivers/net/ethernet/freescale/fman/mac/mac.c | 18 +++--- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h b/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h index ebf7989..50bed14 100644 --- a/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h +++ b/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h @@ -33,8 +33,10 @@ #define __FSL_FMAN_MEMAC_H #include - +#include +#include #include "fsl_enet.h" + /* Num of additional exact match MAC adr regs */ #define MEMAC_NUM_OF_PADDRS 7 @@ -373,7 +375,7 @@ struct memac_cfg { bool tx_pbl_fwd; bool debug_mode; bool wake_on_lan; - bool fixed_link; + struct fixed_phy_status *fixed_link; u16 max_frame_length; u16 pause_quanta; u32 tx_ipg_length; diff --git a/drivers/net/ethernet/freescale/fman/inc/mac.h b/drivers/net/ethernet/freescale/fman/inc/mac.h index f86d0bc..fbeb957 100644 --- a/drivers/net/ethernet/freescale/fman/inc/mac.h +++ b/drivers/net/ethernet/freescale/fman/inc/mac.h @@ -62,7 +62,7 @@ struct mac_device { phy_interface_t phy_if; u32 if_support; bool link; - bool fixed_link; + struct fixed_phy_status *fixed_link; u16 speed; u16 max_speed; struct device_node *phy_node; diff --git a/drivers/net/ethernet/freescale/fman/mac/fm_memac.c b/drivers/net/ethernet/freescale/fman/mac/fm_memac.c index becbb88..3d5ede3 100644 --- a/drivers/net/ethernet/freescale/fman/mac/fm_memac.c +++ b/drivers/net/ethernet/freescale/fman/mac/fm_memac.c @@ -71,9 +71,10 @@ static int memac_mii_write_phy_reg(struct memac_t *memac, u8 phy_addr, } static void setup_sgmii_internal_phy(struct memac_t *memac, u8 phy_addr, -bool fixed_link) +struct fixed_phy_status *fixed_link) { u16 tmp_reg16; + enum ethernet_interface enet_if; enum e_enet_mode enet_mode; /* In case the higher MACs are used (i.e. the MACs that should @@ -81,20 +82,37 @@ static void setup_sgmii_internal_phy(struct memac_t *memac, u8 phy_addr, * Temporary modify enet mode to 1G one, so MII functions can * work correctly. */ + enet_if = ENET_INTERFACE_FROM_MODE(memac->enet_mode); enet_mode = memac->enet_mode; - memac->enet_mode = - MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(memac->enet_mode), - ENET_SPEED_1000); + memac->enet_mode = MAKE_ENET_MODE(enet_if, ENET_SPEED_1000); /* SGMII mode */ tmp_reg16 = PHY_SGMII_IF_MODE_SGMII; if (!fixed_link) /* AN enable */ tmp_reg16 |= PHY_SGMII_IF_MODE_AN; - else - /* Fixed link 1Gb FD */ - tmp_reg16 |= PHY_SGMII_IF_MODE_SPEED_GB | -PHY_SGMII_IF_MODE_DUPLEX_FULL; + else { + switch (fixed_link->speed) { + case 10: + tmp_reg16 |= PHY_SGMII_IF_MODE_SPEED_10M; + memac->enet_mode = MAKE_ENET_MODE(enet_if, + ENET_SPEED_10); + break; + case 100: + tmp_reg16 |= PHY_SGMII_IF_MODE_SPEED_100M; + memac->enet_mode = MAKE_ENET_MODE(enet_if, + ENET_SPEED_100); + break; + case 1000: /* fallthrough */ + default: + tmp_reg16 |= PHY_SGMII_IF_MODE_SPEED_GB; + break; + } + if (fixed_link->duplex) + tmp_reg16 |= PHY_SGMII_IF_MODE_DUPLEX_FULL; + else + tmp_reg16 |= PHY_SGMII_IF_MODE_DUPLEX_HALF; + } memac_mii_write_phy_reg(memac, phy_addr, 0x14, tmp_reg16); /* Device ability according to SGMII specification */ @@ -120,6 +138,7 @@ static void setup_sgmii_internal_phy(struct memac_t *memac, u8 phy_addr, /* Restart AN */ tmp_reg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; else + /* AN disabled */ tmp_reg16 = PHY_SGMII_CR_DEF_VAL & ~PHY_SGMII_CR_AN_ENABLE; memac_mii_write_phy_reg(memac, phy_addr, 0x0, tmp_reg16); @@
[PATCH RFC 1/2] of: separate fixed link parsing from registration
Some drivers may need to parse the fixed link values before registering the fixed link phy or access the status values. Separate the parsing from the actual registration and provide an export for the added parsing function. Signed-off-by: Madalin Bucur --- drivers/of/of_mdio.c| 52 +++-- include/linux/of_mdio.h | 9 + 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index fdc60db..b7e8288 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -284,43 +284,57 @@ bool of_phy_is_fixed_link(struct device_node *np) } EXPORT_SYMBOL(of_phy_is_fixed_link); -int of_phy_register_fixed_link(struct device_node *np) +int of_phy_parse_fixed_link(struct device_node *np, + struct fixed_phy_status *status) { - struct fixed_phy_status status = {}; struct device_node *fixed_link_node; const __be32 *fixed_link_prop; int len; - struct phy_device *phy; /* New binding */ fixed_link_node = of_get_child_by_name(np, "fixed-link"); if (fixed_link_node) { - status.link = 1; - status.duplex = of_property_read_bool(fixed_link_node, - "full-duplex"); - if (of_property_read_u32(fixed_link_node, "speed", &status.speed)) + status->link = 1; + status->duplex = of_property_read_bool(fixed_link_node, + "full-duplex"); + if (of_property_read_u32(fixed_link_node, "speed", +&status->speed)) return -EINVAL; - status.pause = of_property_read_bool(fixed_link_node, "pause"); - status.asym_pause = of_property_read_bool(fixed_link_node, - "asym-pause"); + status->pause = of_property_read_bool(fixed_link_node, + "pause"); + status->asym_pause = of_property_read_bool(fixed_link_node, + "asym-pause"); of_node_put(fixed_link_node); - phy = fixed_phy_register(PHY_POLL, &status, np); - return IS_ERR(phy) ? PTR_ERR(phy) : 0; + + return 0; } /* Old binding */ fixed_link_prop = of_get_property(np, "fixed-link", &len); if (fixed_link_prop && len == (5 * sizeof(__be32))) { - status.link = 1; - status.duplex = be32_to_cpu(fixed_link_prop[1]); - status.speed = be32_to_cpu(fixed_link_prop[2]); - status.pause = be32_to_cpu(fixed_link_prop[3]); - status.asym_pause = be32_to_cpu(fixed_link_prop[4]); - phy = fixed_phy_register(PHY_POLL, &status, np); - return IS_ERR(phy) ? PTR_ERR(phy) : 0; + status->link = 1; + status->duplex = be32_to_cpu(fixed_link_prop[1]); + status->speed = be32_to_cpu(fixed_link_prop[2]); + status->pause = be32_to_cpu(fixed_link_prop[3]); + status->asym_pause = be32_to_cpu(fixed_link_prop[4]); + + return 0; } return -ENODEV; } +EXPORT_SYMBOL(of_phy_parse_fixed_link); + +int of_phy_register_fixed_link(struct device_node *np) +{ + struct phy_device *phy; + struct fixed_phy_status status = {}; + + if (of_phy_parse_fixed_link(np, &status)) + return -ENODEV; + + phy = fixed_phy_register(PHY_POLL, &status, np); + return IS_ERR(phy) ? PTR_ERR(phy) : 0; +} EXPORT_SYMBOL(of_phy_register_fixed_link); #endif diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index 8f2237e..311b2cf 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h @@ -12,6 +12,8 @@ #include #include +struct fixed_phy_status; + #ifdef CONFIG_OF extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np); extern struct phy_device *of_phy_find_device(struct device_node *phy_np); @@ -70,9 +72,16 @@ static inline int of_mdio_parse_addr(struct device *dev, #endif /* CONFIG_OF */ #if defined(CONFIG_OF) && defined(CONFIG_FIXED_PHY) +extern int of_phy_parse_fixed_link(struct device_node *np, + struct fixed_phy_status *status); extern int of_phy_register_fixed_link(struct device_node *np); extern bool of_phy_is_fixed_link(struct device_node *np); #else +static inline int of_phy_parse_fixed_link(struct device_node *np, + struct fixed_phy_status *status) +{ + return -EINVAL; +} static inline int of_phy_register_fixed_link(struct device_node *np) { return -ENOSYS; -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe ne
Re: [PATCH net-next] vxlan: combine VXLAN_FLOWBASED into VXLAN_COLLECT_METADATA
On 08/04/15 at 10:51pm, Alexei Starovoitov wrote: > IFLA_VXLAN_FLOWBASED is useless without IFLA_VXLAN_COLLECT_METADATA, > so combine them into single IFLA_VXLAN_COLLECT_METADATA flag. > 'flowbased' doesn't convey real meaning of the vxlan tunnel mode. > This mode can be used by routing, tc+bpf and ovs. > Only ovs is strictly flow based, so 'collect metadata' is a better > name for this tunnel mode. > > Signed-off-by: Alexei Starovoitov I have no objection since a flag to enable tx only can be added again if needed. As stated in the other thread, the tx only mode which is what VXLAN was capable of doing so far is what motivated the split of flags. Acked-by: Thomas Graf -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH net-next] vxlan: expose COLLECT_METADATA flag to user space
On 08/03/15 at 02:14pm, Jesse Gross wrote: > On Fri, Jul 31, 2015 at 8:41 AM, Alexei Starovoitov wrote: > > thanks. I think exposing collect_metadata for vxlan and in the future > > for other tunnel types is the clean enough way, though the other > > alternative would be to get rid of collect_metadata flag > > from the kernel and do it when flowmode flag is set. Thoughts? > > This seems like a good idea to me - I'm not sure that flow based > tunnels are all that useful without metadata collection enabled and > the fewer interfaces that we have to create for each tunnel type, the > better. The use case at hand where the flag is useful if someone is only doing flow based TX which can be handy if the tunnel id remains unused. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/5] net: rfkill: gpio: remove rfkill_gpio_platform_data
On Wed, 2015-08-05 at 16:39 +0300, Heikki Krogerus wrote: > No more users for it. > > Signed-off-by: Heikki Krogerus > --- > include/linux/rfkill-gpio.h | 37 --- > -- > net/rfkill/Kconfig | 3 +-- > net/rfkill/rfkill-gpio.c| 8 > 3 files changed, 1 insertion(+), 47 deletions(-) > delete mode 100644 include/linux/rfkill-gpio.h > > diff --git a/include/linux/rfkill-gpio.h b/include/linux/rfkill > -gpio.h > deleted file mode 100644 > index 20bcb55..000 > --- a/include/linux/rfkill-gpio.h > +++ /dev/null > @@ -1,37 +0,0 @@ > -/* > - * Copyright (c) 2011, NVIDIA Corporation. > - * > - * 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. > - * > - * This program is distributed in the hope that it will be useful, > but WITHOUT > - * ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or > - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public > License for > - * more details. > - * > - * You should have received a copy of the GNU General Public License > along > - * with this program; if not, write to the Free Software Foundation, > Inc., > - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > - */ > - > - > -#ifndef __RFKILL_GPIO_H > -#define __RFKILL_GPIO_H > - > -#include > -#include > - > -/** > - * struct rfkill_gpio_platform_data - platform data for rfkill gpio > device. > - * for unused gpio's, the expected value is -1. > - * @name:name for the gpio rf kill instance > - */ > - > -struct rfkill_gpio_platform_data { > - char*name; > - enum rfkill_typetype; > -}; > - > -#endif /* __RFKILL_GPIO_H */ > diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig > index 4c10e7e..6320890 100644 > --- a/net/rfkill/Kconfig > +++ b/net/rfkill/Kconfig > @@ -40,5 +40,4 @@ config RFKILL_GPIO > default n > help > If you say yes here you get support of a generic gpio > RFKILL > - driver. The platform should fill in the appropriate fields > in the > - rfkill_gpio_platform_data structure and pass that to the > driver. > + driver. > diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c > index 07323c3..69d92e1 100644 > --- a/net/rfkill/rfkill-gpio.c > +++ b/net/rfkill/rfkill-gpio.c > @@ -27,8 +27,6 @@ > #include > #include > > -#include > - > struct rfkill_gpio_data { > const char *name; > enum rfkill_typetype; > @@ -89,7 +87,6 @@ static int rfkill_gpio_acpi_probe(struct device > *dev, > > static int rfkill_gpio_probe(struct platform_device *pdev) > { > - struct rfkill_gpio_platform_data *pdata = pdev > ->dev.platform_data; > struct rfkill_gpio_data *rfkill; > struct gpio_desc *gpio; > const char *type_name; > @@ -111,11 +108,6 @@ static int rfkill_gpio_probe(struct > platform_device *pdev) > ret = rfkill_gpio_acpi_probe(&pdev->dev, rfkill); > if (ret) > return ret; > - } else if (pdata) { > - rfkill->name = pdata->name; > - rfkill->type = pdata->type; > - } else { > - return -ENODEV; Shouldn't we leave the error path and modify to check if we have device property set set? > } > > rfkill->clk = devm_clk_get(&pdev->dev, NULL); -- Andy Shevchenko Intel Finland Oy -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html