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

Reply via email to