Hi Stephen, > Currently, once we've found a series for a new submission, we check to > ensure that the version of that series matches that of the submission, > and we discard the series if not. The original intention for this was > given in commit 'c21b30525', where this was added: > > There are some things you probably shouldn't do on public mailing > lists, but which people do anyway. > > - [PATCH 1/2] test: Add some lorem ipsum > - [PATCH 2/2] test: Convert to Markdown > - [PATCH v2 1/2] test: Add some lorem ipsum > - [PATCH v2 2/2] test: Convert to Markdown > > We should correctly parse these... > > This is unnecessary for two reasons: > > - If the series is using proper references, then the mechanism that > we use to prevent this issue with unversioned follow ups (also added > in that patch) will work here: namely, we don't add submissions if an > submission with a given number already exists in that series. > - If the series is not using references, we already have a check for > version. > > Seeing as this check is actually causing issues for legitimate typos, we > should just remove this check. Do so, adding a check to ensure we don't > regress.
I'd really really really prefer people used git-send-email and/or whatever the mercurial equivalent is. The tools aren't *that* difficult to use correctly. But having said that, I'm not necessarily opposed to this patch. Not super keen, but not super opposed. 1 comment below. Regards, Daniel > > Signed-off-by: Stephen Finucane <[email protected]> > Closes-bug: #105 > --- > patchwork/parser.py | 1 - > .../tests/series/base-different-versions.mbox | 908 > +++++++++++++++++++++ > patchwork/tests/test_series.py | 18 + > 3 files changed, 926 insertions(+), 1 deletion(-) > create mode 100644 patchwork/tests/series/base-different-versions.mbox > > diff --git a/patchwork/parser.py b/patchwork/parser.py > index 794a5ea..c43fe76 100644 > --- a/patchwork/parser.py > +++ b/patchwork/parser.py > @@ -911,7 +911,6 @@ def parse_mail(mail, list_id=None): > # * the version doesn't match You'll need to remove this comment line too. > # * we have a patch with this number already > if n and ((not series) or > - (series.version != version) or > (SeriesPatch.objects.filter(series=series, > number=x).count() > )): > series = Series(project=project, > diff --git a/patchwork/tests/series/base-different-versions.mbox > b/patchwork/tests/series/base-different-versions.mbox > new file mode 100644 > index 0000000..85bf888 > --- /dev/null > +++ b/patchwork/tests/series/base-different-versions.mbox > @@ -0,0 +1,908 @@ > +From [email protected] Tue Jun 13 19:17:21 2017 > +From: Florian Fainelli <[email protected]> > +To: [email protected] > +Cc: [email protected], [email protected], > + [email protected], [email protected], > + Florian Fainelli <[email protected]> > +Subject: [PATCH net-next v3 0/4] net: dsa: Multi-CPU ground work (v3) > +Date: Tue, 13 Jun 2017 12:17:21 -0700 > +Message-Id: <[email protected]> > +X-Mailer: git-send-email 2.9.3 > +List-ID: <netdev.vger.kernel.org> > + > +Hi all, > + > +This patch series prepares the ground for adding mutliple CPU port support to > +DSA, and starts by removing redundant pieces of information such as > +master_netdev which is cpu_dp->ethernet. Finally drivers are moved away from > +directly accessing ds->dst->cpu_dp and use appropriate helper functions. > + > +Note that if you have Device Tree blobs/platform configurations that are > +currently listing multiple CPU ports, the proposed behavior in > +dsa_ds_get_cpu_dp() will be to return the last bit set in ds->cpu_port_mask. > + > +Future plans include: > +- making dst->cpu_dp a flexible data structure (array, list, you name it) > +- having the ability for drivers to return a default/preferred CPU port (if > + necessary) > + > +Changes in v3: > + > +- removed the last patch since it causes problems with bcm_sf2/b53 in a > + dual-CPU case (root cause known, proper fix underway) > + > +- removed dsa_ds_get_cpu_dp() > + > +Changes in v2: > + > +- added Reviewed-by tags > +- assign port->cpu_dp earlier before ops->setup() has run > + > +Florian Fainelli (5): > + net: dsa: Remove master_netdev and use dst->cpu_dp->netdev > + net: dsa: Relocate master ethtool operations > + net: dsa: Associate slave network device with CPU port > + net: dsa: Introduce dsa_dst_get_cpu_dp() > + net: dsa: Stop accessing ds->dst->cpu_dp in drivers > + > + drivers/net/dsa/b53/b53_common.c | 4 +-- > + drivers/net/dsa/bcm_sf2.c | 10 +++++--- > + drivers/net/dsa/mt7530.c | 6 +++-- > + drivers/net/dsa/mv88e6060.c | 2 +- > + drivers/net/dsa/qca8k.c | 2 +- > + include/net/dsa.h | 29 +++++++++------------- > + net/dsa/dsa.c | 19 ++++---------- > + net/dsa/dsa2.c | 27 ++++++++++++-------- > + net/dsa/dsa_priv.h | 10 ++++++++ > + net/dsa/legacy.c | 23 ++++++++++------- > + net/dsa/slave.c | 53 > ++++++++++++++++++++-------------------- > + net/dsa/tag_brcm.c | 5 ++-- > + net/dsa/tag_ksz.c | 5 ++-- > + net/dsa/tag_qca.c | 3 ++- > + net/dsa/tag_trailer.c | 5 ++-- > + 15 files changed, 107 insertions(+), 96 deletions(-) > + > + > +From [email protected] Tue Jun 13 19:17:22 2017 > +From: Florian Fainelli <[email protected]> > +To: [email protected] > +Cc: [email protected], [email protected], > + [email protected], [email protected], > + Florian Fainelli <[email protected]> > +Subject: [PATCH 1/4] net: dsa: Remove master_netdev and use > + dst->cpu_dp->netdev > +Date: Tue, 13 Jun 2017 12:17:22 -0700 > +Message-Id: <[email protected]> > +X-Mailer: git-send-email 2.9.3 > +In-Reply-To: <[email protected]> > +References: <[email protected]> > +List-ID: <netdev.vger.kernel.org> > + > +In preparation for supporting multiple CPU ports, remove > +dst->master_netdev and ds->master_netdev and replace them with only one > +instance of the common object we have for a port: struct > +dsa_port::netdev. ds->master_netdev is currently write only and would be > +helpful in the case where we have two switches, both with CPU ports, and > +also connected within each other, which the multi-CPU port patch series > +would address. > + > +While at it, introduce a helper function used in net/dsa/slave.c to > +immediately get a reference on the master network device called > +dsa_master_netdev(). > + > +Reviewed-by: Vivien Didelot <[email protected]> > +Signed-off-by: Florian Fainelli <[email protected]> > +--- > + drivers/net/dsa/bcm_sf2.c | 4 ++-- > + drivers/net/dsa/mt7530.c | 4 ++-- > + include/net/dsa.h | 5 ----- > + net/dsa/dsa.c | 9 ++------- > + net/dsa/dsa2.c | 18 +++++++----------- > + net/dsa/dsa_priv.h | 5 +++++ > + net/dsa/legacy.c | 22 +++++++++++++--------- > + net/dsa/slave.c | 20 +++++++++----------- > + 8 files changed, 40 insertions(+), 47 deletions(-) > + > +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c > +index 687a8bae5d73..76e98e8ed315 100644 > +--- a/drivers/net/dsa/bcm_sf2.c > ++++ b/drivers/net/dsa/bcm_sf2.c > +@@ -806,7 +806,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds) > + static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port, > + struct ethtool_wolinfo *wol) > + { > +- struct net_device *p = ds->dst[ds->index].master_netdev; > ++ struct net_device *p = ds->dst[ds->index].cpu_dp->netdev; > + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); > + struct ethtool_wolinfo pwol; > + > +@@ -829,7 +829,7 @@ static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, > int port, > + static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port, > + struct ethtool_wolinfo *wol) > + { > +- struct net_device *p = ds->dst[ds->index].master_netdev; > ++ struct net_device *p = ds->dst[ds->index].cpu_dp->netdev; > + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); > + s8 cpu_port = ds->dst->cpu_dp->index; > + struct ethtool_wolinfo pwol; > +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c > +index 25e00d5e0eec..1e46418a3b74 100644 > +--- a/drivers/net/dsa/mt7530.c > ++++ b/drivers/net/dsa/mt7530.c > +@@ -912,11 +912,11 @@ mt7530_setup(struct dsa_switch *ds) > + struct device_node *dn; > + struct mt7530_dummy_poll p; > + > +- /* The parent node of master_netdev which holds the common system > ++ /* The parent node of cpu_dp->netdev which holds the common system > + * controller also is the container for two GMACs nodes representing > + * as two netdev instances. > + */ > +- dn = ds->master_netdev->dev.of_node->parent; > ++ dn = ds->dst->cpu_dp->netdev->dev.of_node->parent; > + priv->ethernet = syscon_node_to_regmap(dn); > + if (IS_ERR(priv->ethernet)) > + return PTR_ERR(priv->ethernet); > +diff --git a/include/net/dsa.h b/include/net/dsa.h > +index 2effb0af9d7c..b2fb53f5e28e 100644 > +--- a/include/net/dsa.h > ++++ b/include/net/dsa.h > +@@ -227,11 +227,6 @@ struct dsa_switch { > + s8 rtable[DSA_MAX_SWITCHES]; > + > + /* > +- * The lower device this switch uses to talk to the host > +- */ > +- struct net_device *master_netdev; > +- > +- /* > + * Slave mii_bus and devices for the individual ports. > + */ > + u32 dsa_port_mask; > +diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c > +index 517215391514..6aacc2314a8f 100644 > +--- a/net/dsa/dsa.c > ++++ b/net/dsa/dsa.c > +@@ -118,10 +118,7 @@ int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp) > + struct net_device *master; > + struct ethtool_ops *cpu_ops; > + > +- master = ds->dst->master_netdev; > +- if (ds->master_netdev) > +- master = ds->master_netdev; > +- > ++ master = ds->dst->cpu_dp->netdev; > + cpu_ops = devm_kzalloc(ds->dev, sizeof(*cpu_ops), GFP_KERNEL); > + if (!cpu_ops) > + return -ENOMEM; > +@@ -142,9 +139,7 @@ void dsa_cpu_port_ethtool_restore(struct dsa_port > *cpu_dp) > + struct dsa_switch *ds = cpu_dp->ds; > + struct net_device *master; > + > +- master = ds->dst->master_netdev; > +- if (ds->master_netdev) > +- master = ds->master_netdev; > ++ master = ds->dst->cpu_dp->netdev; > + > + master->ethtool_ops = ds->dst->master_orig_ethtool_ops; > + } > +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c > +index f88e1dddb74a..ab48c4f989da 100644 > +--- a/net/dsa/dsa2.c > ++++ b/net/dsa/dsa2.c > +@@ -337,7 +337,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, > struct dsa_switch *ds) > + return err; > + > + if (ds->ops->set_addr) { > +- err = ds->ops->set_addr(ds, dst->master_netdev->dev_addr); > ++ err = ds->ops->set_addr(ds, dst->cpu_dp->netdev->dev_addr); > + if (err < 0) > + return err; > + } > +@@ -444,7 +444,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst) > + * sent to the tag format's receive function. > + */ > + wmb(); > +- dst->master_netdev->dsa_ptr = dst; > ++ dst->cpu_dp->netdev->dsa_ptr = dst; > + dst->applied = true; > + > + return 0; > +@@ -458,7 +458,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst) > + if (!dst->applied) > + return; > + > +- dst->master_netdev->dsa_ptr = NULL; > ++ dst->cpu_dp->netdev->dsa_ptr = NULL; > + > + /* If we used a tagging format that doesn't have an ethertype > + * field, make sure that all packets from this point get sent > +@@ -504,14 +504,10 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 > index, > + if (!ethernet_dev) > + return -EPROBE_DEFER; > + > +- if (!ds->master_netdev) > +- ds->master_netdev = ethernet_dev; > +- > +- if (!dst->master_netdev) > +- dst->master_netdev = ethernet_dev; > +- > +- if (!dst->cpu_dp) > ++ if (!dst->cpu_dp) { > + dst->cpu_dp = port; > ++ dst->cpu_dp->netdev = ethernet_dev; > ++ } > + > + tag_protocol = ds->ops->get_tag_protocol(ds); > + dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol); > +@@ -578,7 +574,7 @@ static int dsa_dst_parse(struct dsa_switch_tree *dst) > + return err; > + } > + > +- if (!dst->master_netdev) { > ++ if (!dst->cpu_dp->netdev) { > + pr_warn("Tree has no master device\n"); > + return -EINVAL; > + } > +diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h > +index 66ee248796c8..5c510f4ba0ce 100644 > +--- a/net/dsa/dsa_priv.h > ++++ b/net/dsa/dsa_priv.h > +@@ -183,4 +183,9 @@ extern const struct dsa_device_ops qca_netdev_ops; > + /* tag_trailer.c */ > + extern const struct dsa_device_ops trailer_netdev_ops; > + > ++static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p) > ++{ > ++ return p->dp->ds->dst->cpu_dp->netdev; > ++} > ++ > + #endif > +diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c > +index 3a56de8f51a8..5d4f6ffa3424 100644 > +--- a/net/dsa/legacy.c > ++++ b/net/dsa/legacy.c > +@@ -101,9 +101,12 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, > struct device *parent) > + struct dsa_switch_tree *dst = ds->dst; > + struct dsa_chip_data *cd = ds->cd; > + bool valid_name_found = false; > ++ struct net_device *master; > + int index = ds->index; > + int i, ret; > + > ++ master = dst->cpu_dp->netdev; > ++ > + /* > + * Validate supplied switch configuration. > + */ > +@@ -116,7 +119,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, > struct device *parent) > + > + if (!strcmp(name, "cpu")) { > + if (dst->cpu_dp) { > +- netdev_err(dst->master_netdev, > ++ netdev_err(master, > + "multiple cpu ports?!\n"); > + return -EINVAL; > + } > +@@ -168,7 +171,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, > struct device *parent) > + return ret; > + > + if (ops->set_addr) { > +- ret = ops->set_addr(ds, dst->master_netdev->dev_addr); > ++ ret = ops->set_addr(ds, master->dev_addr); > + if (ret < 0) > + return ret; > + } > +@@ -195,14 +198,14 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, > struct device *parent) > + > + ret = dsa_slave_create(ds, parent, i, cd->port_names[i]); > + if (ret < 0) > +- netdev_err(dst->master_netdev, "[%d]: can't create dsa > slave device for port %d(%s): %d\n", > ++ netdev_err(master, "[%d]: can't create dsa slave device > for port %d(%s): %d\n", > + index, i, cd->port_names[i], ret); > + } > + > + /* Perform configuration of the CPU and DSA ports */ > + ret = dsa_cpu_dsa_setups(ds, parent); > + if (ret < 0) > +- netdev_err(dst->master_netdev, "[%d] : can't configure CPU and > DSA ports\n", > ++ netdev_err(master, "[%d] : can't configure CPU and DSA ports\n", > + index); > + > + ret = dsa_cpu_port_ethtool_setup(ds->dst->cpu_dp); > +@@ -217,6 +220,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, > + struct device *parent, struct device *host_dev) > + { > + struct dsa_chip_data *cd = dst->pd->chip + index; > ++ struct net_device *master = dst->cpu_dp->netdev; > + const struct dsa_switch_ops *ops; > + struct dsa_switch *ds; > + int ret; > +@@ -228,11 +232,11 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int > index, > + */ > + ops = dsa_switch_probe(parent, host_dev, cd->sw_addr, &name, &priv); > + if (!ops) { > +- netdev_err(dst->master_netdev, "[%d]: could not detect attached > switch\n", > ++ netdev_err(master, "[%d]: could not detect attached switch\n", > + index); > + return ERR_PTR(-EINVAL); > + } > +- netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n", > ++ netdev_info(master, "[%d]: detected a %s switch\n", > + index, name); > + > + > +@@ -575,7 +579,7 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, > struct net_device *dev, > + unsigned configured = 0; > + > + dst->pd = pd; > +- dst->master_netdev = dev; > ++ dst->cpu_dp->netdev = dev; > + > + for (i = 0; i < pd->nr_chips; i++) { > + struct dsa_switch *ds; > +@@ -671,7 +675,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst) > + { > + int i; > + > +- dst->master_netdev->dsa_ptr = NULL; > ++ dst->cpu_dp->netdev->dsa_ptr = NULL; > + > + /* If we used a tagging format that doesn't have an ethertype > + * field, make sure that all packets from this point get sent > +@@ -688,7 +692,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst) > + > + dsa_cpu_port_ethtool_restore(dst->cpu_dp); > + > +- dev_put(dst->master_netdev); > ++ dev_put(dst->cpu_dp->netdev); > + } > + > + static int dsa_remove(struct platform_device *pdev) > +diff --git a/net/dsa/slave.c b/net/dsa/slave.c > +index 5e45ae5c3f71..95031b31d64b 100644 > +--- a/net/dsa/slave.c > ++++ b/net/dsa/slave.c > +@@ -66,7 +66,7 @@ static int dsa_slave_get_iflink(const struct net_device > *dev) > + { > + struct dsa_slave_priv *p = netdev_priv(dev); > + > +- return p->dp->ds->dst->master_netdev->ifindex; > ++ return dsa_master_netdev(p)->ifindex; > + } > + > + static int dsa_slave_open(struct net_device *dev) > +@@ -74,7 +74,7 @@ static int dsa_slave_open(struct net_device *dev) > + struct dsa_slave_priv *p = netdev_priv(dev); > + struct dsa_port *dp = p->dp; > + struct dsa_switch *ds = dp->ds; > +- struct net_device *master = ds->dst->master_netdev; > ++ struct net_device *master = dsa_master_netdev(p); > + u8 stp_state = dp->bridge_dev ? BR_STATE_BLOCKING : BR_STATE_FORWARDING; > + int err; > + > +@@ -127,7 +127,7 @@ static int dsa_slave_open(struct net_device *dev) > + static int dsa_slave_close(struct net_device *dev) > + { > + struct dsa_slave_priv *p = netdev_priv(dev); > +- struct net_device *master = p->dp->ds->dst->master_netdev; > ++ struct net_device *master = dsa_master_netdev(p); > + struct dsa_switch *ds = p->dp->ds; > + > + if (p->phy) > +@@ -154,7 +154,7 @@ static int dsa_slave_close(struct net_device *dev) > + static void dsa_slave_change_rx_flags(struct net_device *dev, int change) > + { > + struct dsa_slave_priv *p = netdev_priv(dev); > +- struct net_device *master = p->dp->ds->dst->master_netdev; > ++ struct net_device *master = dsa_master_netdev(p); > + > + if (change & IFF_ALLMULTI) > + dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1); > +@@ -165,7 +165,7 @@ static void dsa_slave_change_rx_flags(struct net_device > *dev, int change) > + static void dsa_slave_set_rx_mode(struct net_device *dev) > + { > + struct dsa_slave_priv *p = netdev_priv(dev); > +- struct net_device *master = p->dp->ds->dst->master_netdev; > ++ struct net_device *master = dsa_master_netdev(p); > + > + dev_mc_sync(master, dev); > + dev_uc_sync(master, dev); > +@@ -174,7 +174,7 @@ static void dsa_slave_set_rx_mode(struct net_device *dev) > + static int dsa_slave_set_mac_address(struct net_device *dev, void *a) > + { > + struct dsa_slave_priv *p = netdev_priv(dev); > +- struct net_device *master = p->dp->ds->dst->master_netdev; > ++ struct net_device *master = dsa_master_netdev(p); > + struct sockaddr *addr = a; > + int err; > + > +@@ -375,7 +375,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, > struct net_device *dev) > + /* Queue the SKB for transmission on the parent interface, but > + * do not modify its EtherType > + */ > +- nskb->dev = p->dp->ds->dst->master_netdev; > ++ nskb->dev = dsa_master_netdev(p); > + dev_queue_xmit(nskb); > + > + return NETDEV_TX_OK; > +@@ -685,7 +685,7 @@ static int dsa_slave_netpoll_setup(struct net_device > *dev, > + { > + struct dsa_slave_priv *p = netdev_priv(dev); > + struct dsa_switch *ds = p->dp->ds; > +- struct net_device *master = ds->dst->master_netdev; > ++ struct net_device *master = dsa_master_netdev(p); > + struct netpoll *netpoll; > + int err = 0; > + > +@@ -1143,9 +1143,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct > device *parent, > + struct dsa_slave_priv *p; > + int ret; > + > +- master = ds->dst->master_netdev; > +- if (ds->master_netdev) > +- master = ds->master_netdev; > ++ master = ds->dst->cpu_dp->netdev; > + > + slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name, > + NET_NAME_UNKNOWN, ether_setup); > + > + > +From [email protected] Tue Jun 13 19:17:23 2017 > +From: Florian Fainelli <[email protected]> > +To: [email protected] > +Cc: [email protected], [email protected], > + [email protected], [email protected], > + Florian Fainelli <[email protected]> > +Subject: [PATCH 2/4] net: dsa: Relocate master ethtool operations > +Date: Tue, 13 Jun 2017 12:17:23 -0700 > +Message-Id: <[email protected]> > +X-Mailer: git-send-email 2.9.3 > +In-Reply-To: <[email protected]> > +References: <[email protected]> > +List-ID: <netdev.vger.kernel.org> > + > +Relocate master_ethtool_ops and master_orig_ethtool_ops into struct > +dsa_port in order to be both consistent, and make things self contained > +within the dsa_port structure. > + > +This is a preliminary change to supporting multiple CPU port interfaces. > + > +Reviewed-by: Vivien Didelot <[email protected]> > +Signed-off-by: Florian Fainelli <[email protected]> > +--- > + include/net/dsa.h | 17 +++++------------ > + net/dsa/dsa.c | 16 ++++++---------- > + net/dsa/slave.c | 16 ++++++++-------- > + 3 files changed, 19 insertions(+), 30 deletions(-) > + > +diff --git a/include/net/dsa.h b/include/net/dsa.h > +index b2fb53f5e28e..7e93869819f9 100644 > +--- a/include/net/dsa.h > ++++ b/include/net/dsa.h > +@@ -122,12 +122,6 @@ struct dsa_switch_tree { > + */ > + struct dsa_platform_data *pd; > + > +- /* > +- * Reference to network device to use, and which tagging > +- * protocol to use. > +- */ > +- struct net_device *master_netdev; > +- > + /* Copy of tag_ops->rcv for faster access in hot path */ > + struct sk_buff * (*rcv)(struct sk_buff *skb, > + struct net_device *dev, > +@@ -135,12 +129,6 @@ struct dsa_switch_tree { > + struct net_device *orig_dev); > + > + /* > +- * Original copy of the master netdev ethtool_ops > +- */ > +- struct ethtool_ops master_ethtool_ops; > +- const struct ethtool_ops *master_orig_ethtool_ops; > +- > +- /* > + * The switch port to which the CPU is attached. > + */ > + struct dsa_port *cpu_dp; > +@@ -189,6 +177,11 @@ struct dsa_port { > + u8 stp_state; > + struct net_device *bridge_dev; > + struct devlink_port devlink_port; > ++ /* > ++ * Original copy of the master netdev ethtool_ops > ++ */ > ++ struct ethtool_ops ethtool_ops; > ++ const struct ethtool_ops *orig_ethtool_ops; > + }; > + > + struct dsa_switch { > +diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c > +index 6aacc2314a8f..416ac4ef9ba9 100644 > +--- a/net/dsa/dsa.c > ++++ b/net/dsa/dsa.c > +@@ -118,15 +118,16 @@ int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp) > + struct net_device *master; > + struct ethtool_ops *cpu_ops; > + > +- master = ds->dst->cpu_dp->netdev; > ++ master = cpu_dp->netdev; > ++ > + cpu_ops = devm_kzalloc(ds->dev, sizeof(*cpu_ops), GFP_KERNEL); > + if (!cpu_ops) > + return -ENOMEM; > + > +- memcpy(&ds->dst->master_ethtool_ops, master->ethtool_ops, > ++ memcpy(&cpu_dp->ethtool_ops, master->ethtool_ops, > + sizeof(struct ethtool_ops)); > +- ds->dst->master_orig_ethtool_ops = master->ethtool_ops; > +- memcpy(cpu_ops, &ds->dst->master_ethtool_ops, > ++ cpu_dp->orig_ethtool_ops = master->ethtool_ops; > ++ memcpy(cpu_ops, &cpu_dp->ethtool_ops, > + sizeof(struct ethtool_ops)); > + dsa_cpu_port_ethtool_init(cpu_ops); > + master->ethtool_ops = cpu_ops; > +@@ -136,12 +137,7 @@ int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp) > + > + void dsa_cpu_port_ethtool_restore(struct dsa_port *cpu_dp) > + { > +- struct dsa_switch *ds = cpu_dp->ds; > +- struct net_device *master; > +- > +- master = ds->dst->cpu_dp->netdev; > +- > +- master->ethtool_ops = ds->dst->master_orig_ethtool_ops; > ++ cpu_dp->netdev->ethtool_ops = cpu_dp->orig_ethtool_ops; > + } > + > + void dsa_cpu_dsa_destroy(struct dsa_port *port) > +diff --git a/net/dsa/slave.c b/net/dsa/slave.c > +index 95031b31d64b..c33db4e3b445 100644 > +--- a/net/dsa/slave.c > ++++ b/net/dsa/slave.c > +@@ -524,10 +524,10 @@ static void dsa_cpu_port_get_ethtool_stats(struct > net_device *dev, > + s8 cpu_port = dst->cpu_dp->index; > + int count = 0; > + > +- if (dst->master_ethtool_ops.get_sset_count) { > +- count = dst->master_ethtool_ops.get_sset_count(dev, > ++ if (dst->cpu_dp->ethtool_ops.get_sset_count) { > ++ count = dst->cpu_dp->ethtool_ops.get_sset_count(dev, > + ETH_SS_STATS); > +- dst->master_ethtool_ops.get_ethtool_stats(dev, stats, data); > ++ dst->cpu_dp->ethtool_ops.get_ethtool_stats(dev, stats, data); > + } > + > + if (ds->ops->get_ethtool_stats) > +@@ -540,8 +540,8 @@ static int dsa_cpu_port_get_sset_count(struct net_device > *dev, int sset) > + struct dsa_switch *ds = dst->cpu_dp->ds; > + int count = 0; > + > +- if (dst->master_ethtool_ops.get_sset_count) > +- count += dst->master_ethtool_ops.get_sset_count(dev, sset); > ++ if (dst->cpu_dp->ethtool_ops.get_sset_count) > ++ count += dst->cpu_dp->ethtool_ops.get_sset_count(dev, sset); > + > + if (sset == ETH_SS_STATS && ds->ops->get_sset_count) > + count += ds->ops->get_sset_count(ds); > +@@ -565,10 +565,10 @@ static void dsa_cpu_port_get_strings(struct net_device > *dev, > + /* We do not want to be NULL-terminated, since this is a prefix */ > + pfx[sizeof(pfx) - 1] = '_'; > + > +- if (dst->master_ethtool_ops.get_sset_count) { > +- mcount = dst->master_ethtool_ops.get_sset_count(dev, > ++ if (dst->cpu_dp->ethtool_ops.get_sset_count) { > ++ mcount = dst->cpu_dp->ethtool_ops.get_sset_count(dev, > + ETH_SS_STATS); > +- dst->master_ethtool_ops.get_strings(dev, stringset, data); > ++ dst->cpu_dp->ethtool_ops.get_strings(dev, stringset, data); > + } > + > + if (stringset == ETH_SS_STATS && ds->ops->get_strings) { > + > + > +From [email protected] Tue Jun 13 19:17:24 2017 > +From: Florian Fainelli <[email protected]> > +To: [email protected] > +Cc: [email protected], [email protected], > + [email protected], [email protected], > + Florian Fainelli <[email protected]> > +Subject: [PATCH 3/4] net: dsa: Associate slave network device with CPU port > +Date: Tue, 13 Jun 2017 12:17:24 -0700 > +Message-Id: <[email protected]> > +X-Mailer: git-send-email 2.9.3 > +In-Reply-To: <[email protected]> > +References: <[email protected]> > +List-ID: <netdev.vger.kernel.org> > + > +In preparation for supporting multiple CPU ports with DSA, have the > +dsa_port structure know which CPU it is associated with. This will be > +important in order to make sure the correct CPU is used for transmission > +of the frames. If not for functional reasons, for performance (e.g: load > +balancing) and forwarding decisions. > + > +Signed-off-by: Florian Fainelli <[email protected]> > +Reviewed-by: Vivien Didelot <[email protected]> > +--- > + include/net/dsa.h | 1 + > + net/dsa/dsa2.c | 11 +++++++++++ > + net/dsa/dsa_priv.h | 2 +- > + net/dsa/legacy.c | 1 + > + net/dsa/slave.c | 4 +++- > + 5 files changed, 17 insertions(+), 2 deletions(-) > + > +diff --git a/include/net/dsa.h b/include/net/dsa.h > +index 7e93869819f9..58969b9a090c 100644 > +--- a/include/net/dsa.h > ++++ b/include/net/dsa.h > +@@ -171,6 +171,7 @@ struct dsa_port { > + struct dsa_switch *ds; > + unsigned int index; > + const char *name; > ++ struct dsa_port *cpu_dp; > + struct net_device *netdev; > + struct device_node *dn; > + unsigned int ageing_time; > +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c > +index ab48c4f989da..52af8401af07 100644 > +--- a/net/dsa/dsa2.c > ++++ b/net/dsa/dsa2.c > +@@ -490,6 +490,8 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 > index, > + enum dsa_tag_protocol tag_protocol; > + struct net_device *ethernet_dev; > + struct device_node *ethernet; > ++ struct dsa_port *p; > ++ unsigned int i; > + > + if (port->dn) { > + ethernet = of_parse_phandle(port->dn, "ethernet", 0); > +@@ -507,6 +509,15 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 > index, > + if (!dst->cpu_dp) { > + dst->cpu_dp = port; > + dst->cpu_dp->netdev = ethernet_dev; > ++ > ++ for (i = 0; i < ds->num_ports; i++) { > ++ p = &ds->ports[i]; > ++ if (!dsa_port_is_valid(p) || > ++ i == index) > ++ continue; > ++ > ++ p->cpu_dp = port; > ++ } > + } > + > + tag_protocol = ds->ops->get_tag_protocol(ds); > +diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h > +index 5c510f4ba0ce..7c2326f3b538 100644 > +--- a/net/dsa/dsa_priv.h > ++++ b/net/dsa/dsa_priv.h > +@@ -185,7 +185,7 @@ extern const struct dsa_device_ops trailer_netdev_ops; > + > + static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p) > + { > +- return p->dp->ds->dst->cpu_dp->netdev; > ++ return p->dp->cpu_dp->netdev; > + } > + > + #endif > +diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c > +index 5d4f6ffa3424..e60906125375 100644 > +--- a/net/dsa/legacy.c > ++++ b/net/dsa/legacy.c > +@@ -129,6 +129,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, > struct device *parent) > + ds->dsa_port_mask |= 1 << i; > + } else { > + ds->enabled_port_mask |= 1 << i; > ++ ds->ports[i].cpu_dp = dst->cpu_dp; > + } > + valid_name_found = true; > + } > +diff --git a/net/dsa/slave.c b/net/dsa/slave.c > +index c33db4e3b445..427f8afcfaf3 100644 > +--- a/net/dsa/slave.c > ++++ b/net/dsa/slave.c > +@@ -1141,9 +1141,11 @@ int dsa_slave_create(struct dsa_switch *ds, struct > device *parent, > + struct net_device *master; > + struct net_device *slave_dev; > + struct dsa_slave_priv *p; > ++ struct dsa_port *cpu_dp; > + int ret; > + > +- master = ds->dst->cpu_dp->netdev; > ++ cpu_dp = ds->dst->cpu_dp; > ++ master = cpu_dp->netdev; > + > + slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name, > + NET_NAME_UNKNOWN, ether_setup); > + > + > +From [email protected] Tue Jun 13 19:17:25 2017 > +From: Florian Fainelli <[email protected]> > +To: [email protected] > +Cc: [email protected], [email protected], > + [email protected], [email protected], > + Florian Fainelli <[email protected]> > +Subject: [PATCH 4/4] net: dsa: Introduce dsa_get_cpu_port() > +Date: Tue, 13 Jun 2017 12:17:25 -0700 > +Message-Id: <[email protected]> > +X-Mailer: git-send-email 2.9.3 > +In-Reply-To: <[email protected]> > +References: <[email protected]> > +List-ID: <netdev.vger.kernel.org> > + > +Introduce a helper function which will return a reference to the CPU > +port used in a dsa_switch_tree. Right now this is a singleton, but this > +will change once we introduce multi-CPU port support, so ease the > +transition by converting the affected code paths. > + > +Reviewed-by: Vivien Didelot <[email protected]> > +Signed-off-by: Florian Fainelli <[email protected]> > +--- > + net/dsa/dsa_priv.h | 5 +++++ > + net/dsa/slave.c | 31 ++++++++++++++++--------------- > + net/dsa/tag_brcm.c | 5 ++--- > + net/dsa/tag_ksz.c | 5 ++--- > + net/dsa/tag_qca.c | 3 ++- > + net/dsa/tag_trailer.c | 5 ++--- > + 6 files changed, 29 insertions(+), 25 deletions(-) > + > +diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h > +index 7c2326f3b538..55982cc39b24 100644 > +--- a/net/dsa/dsa_priv.h > ++++ b/net/dsa/dsa_priv.h > +@@ -188,4 +188,9 @@ static inline struct net_device > *dsa_master_netdev(struct dsa_slave_priv *p) > + return p->dp->cpu_dp->netdev; > + } > + > ++static inline struct dsa_port *dsa_get_cpu_port(struct dsa_switch_tree *dst) > ++{ > ++ return dst->cpu_dp; > ++} > ++ > + #endif > +diff --git a/net/dsa/slave.c b/net/dsa/slave.c > +index 427f8afcfaf3..845e0c3f871e 100644 > +--- a/net/dsa/slave.c > ++++ b/net/dsa/slave.c > +@@ -520,14 +520,14 @@ static void dsa_cpu_port_get_ethtool_stats(struct > net_device *dev, > + uint64_t *data) > + { > + struct dsa_switch_tree *dst = dev->dsa_ptr; > +- struct dsa_switch *ds = dst->cpu_dp->ds; > +- s8 cpu_port = dst->cpu_dp->index; > ++ struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); > ++ struct dsa_switch *ds = cpu_dp->ds; > ++ s8 cpu_port = cpu_dp->index; > + int count = 0; > + > +- if (dst->cpu_dp->ethtool_ops.get_sset_count) { > +- count = dst->cpu_dp->ethtool_ops.get_sset_count(dev, > +- ETH_SS_STATS); > +- dst->cpu_dp->ethtool_ops.get_ethtool_stats(dev, stats, data); > ++ if (cpu_dp->ethtool_ops.get_sset_count) { > ++ count = cpu_dp->ethtool_ops.get_sset_count(dev, ETH_SS_STATS); > ++ cpu_dp->ethtool_ops.get_ethtool_stats(dev, stats, data); > + } > + > + if (ds->ops->get_ethtool_stats) > +@@ -537,11 +537,12 @@ static void dsa_cpu_port_get_ethtool_stats(struct > net_device *dev, > + static int dsa_cpu_port_get_sset_count(struct net_device *dev, int sset) > + { > + struct dsa_switch_tree *dst = dev->dsa_ptr; > +- struct dsa_switch *ds = dst->cpu_dp->ds; > ++ struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); > ++ struct dsa_switch *ds = cpu_dp->ds; > + int count = 0; > + > +- if (dst->cpu_dp->ethtool_ops.get_sset_count) > +- count += dst->cpu_dp->ethtool_ops.get_sset_count(dev, sset); > ++ if (cpu_dp->ethtool_ops.get_sset_count) > ++ count += cpu_dp->ethtool_ops.get_sset_count(dev, sset); > + > + if (sset == ETH_SS_STATS && ds->ops->get_sset_count) > + count += ds->ops->get_sset_count(ds); > +@@ -553,8 +554,9 @@ static void dsa_cpu_port_get_strings(struct net_device > *dev, > + uint32_t stringset, uint8_t *data) > + { > + struct dsa_switch_tree *dst = dev->dsa_ptr; > +- struct dsa_switch *ds = dst->cpu_dp->ds; > +- s8 cpu_port = dst->cpu_dp->index; > ++ struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); > ++ struct dsa_switch *ds = cpu_dp->ds; > ++ s8 cpu_port = cpu_dp->index; > + int len = ETH_GSTRING_LEN; > + int mcount = 0, count; > + unsigned int i; > +@@ -565,10 +567,9 @@ static void dsa_cpu_port_get_strings(struct net_device > *dev, > + /* We do not want to be NULL-terminated, since this is a prefix */ > + pfx[sizeof(pfx) - 1] = '_'; > + > +- if (dst->cpu_dp->ethtool_ops.get_sset_count) { > +- mcount = dst->cpu_dp->ethtool_ops.get_sset_count(dev, > +- ETH_SS_STATS); > +- dst->cpu_dp->ethtool_ops.get_strings(dev, stringset, data); > ++ if (cpu_dp->ethtool_ops.get_sset_count) { > ++ mcount = cpu_dp->ethtool_ops.get_sset_count(dev, ETH_SS_STATS); > ++ cpu_dp->ethtool_ops.get_strings(dev, stringset, data); > + } > + > + if (stringset == ETH_SS_STATS && ds->ops->get_strings) { > +diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c > +index c03860907f28..c697d9815177 100644 > +--- a/net/dsa/tag_brcm.c > ++++ b/net/dsa/tag_brcm.c > +@@ -93,12 +93,11 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, > struct net_device *dev, > + struct net_device *orig_dev) > + { > + struct dsa_switch_tree *dst = dev->dsa_ptr; > +- struct dsa_switch *ds; > ++ struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); > ++ struct dsa_switch *ds = cpu_dp->ds; > + int source_port; > + u8 *brcm_tag; > + > +- ds = dst->cpu_dp->ds; > +- > + if (unlikely(!pskb_may_pull(skb, BRCM_TAG_LEN))) > + return NULL; > + > +diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c > +index b94a334a1d02..fab41de8e983 100644 > +--- a/net/dsa/tag_ksz.c > ++++ b/net/dsa/tag_ksz.c > +@@ -75,12 +75,11 @@ static struct sk_buff *ksz_rcv(struct sk_buff *skb, > struct net_device *dev, > + struct net_device *orig_dev) > + { > + struct dsa_switch_tree *dst = dev->dsa_ptr; > +- struct dsa_switch *ds; > ++ struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); > ++ struct dsa_switch *ds = cpu_dp->ds; > + u8 *tag; > + int source_port; > + > +- ds = dst->cpu_dp->ds; > +- > + tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; > + > + source_port = tag[0] & 7; > +diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c > +index 4f43cf0b4eff..1867a3d11f28 100644 > +--- a/net/dsa/tag_qca.c > ++++ b/net/dsa/tag_qca.c > +@@ -67,6 +67,7 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, > struct net_device *dev, > + struct net_device *orig_dev) > + { > + struct dsa_switch_tree *dst = dev->dsa_ptr; > ++ struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); > + struct dsa_switch *ds; > + u8 ver; > + int port; > +@@ -95,7 +96,7 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, > struct net_device *dev, > + /* This protocol doesn't support cascading multiple switches so it's > + * safe to assume the switch is first in the tree > + */ > +- ds = dst->cpu_dp->ds; > ++ ds = cpu_dp->ds; > + if (!ds) > + return NULL; > + > +diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c > +index b4f6db094409..172f13167896 100644 > +--- a/net/dsa/tag_trailer.c > ++++ b/net/dsa/tag_trailer.c > +@@ -61,12 +61,11 @@ static struct sk_buff *trailer_rcv(struct sk_buff *skb, > struct net_device *dev, > + struct net_device *orig_dev) > + { > + struct dsa_switch_tree *dst = dev->dsa_ptr; > +- struct dsa_switch *ds; > ++ struct dsa_port *cpu_dp = dsa_get_cpu_port(dst); > ++ struct dsa_switch *ds = cpu_dp->ds; > + u8 *trailer; > + int source_port; > + > +- ds = dst->cpu_dp->ds; > +- > + if (skb_linearize(skb)) > + return NULL; > + > diff --git a/patchwork/tests/test_series.py b/patchwork/tests/test_series.py > index 0a33b75..390ee51 100644 > --- a/patchwork/tests/test_series.py > +++ b/patchwork/tests/test_series.py > @@ -185,6 +185,24 @@ class BaseSeriesTest(_BaseTestCase): > > self.assertSerialized(patches_a + patches_b, [2, 2]) > > + def test_different_versions(self): > + """Series received with different version on cover to patches. > + > + Input: > + - [PATCH net-next v3 0/4] net: dsa: Multi-CPU ground work (v3) > + - [PATCH 1/4] net: dsa: Remove master_netdev and use > + dst->cpu_dp->netdev > + - [PATCH 2/4] net: dsa: Relocate master ethtool operations > + - [PATCH 3/4] net: dsa: Associate slave network device with CPU > + port > + - [PATCH 4/4] net: dsa: Introduce dsa_get_cpu_port() > + """ > + covers, patches, _ = self._parse_mbox( > + 'base-different-versions.mbox', [1, 4, 0]) > + > + self.assertSerialized(covers, [1]) > + self.assertSerialized(patches, [4]) > + > def test_multiple_references(self): > """Series received with multiple reference headers. > > -- > 2.9.4 > > _______________________________________________ > Patchwork mailing list > [email protected] > https://lists.ozlabs.org/listinfo/patchwork _______________________________________________ Patchwork mailing list [email protected] https://lists.ozlabs.org/listinfo/patchwork
