WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [xen/stable-2.6.32.x PATCH 5/5] rtnetlink: make SR-IOV VF in

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [xen/stable-2.6.32.x PATCH 5/5] rtnetlink: make SR-IOV VF interface symmetric
From: "Rose, Gregory V" <gregory.v.rose@xxxxxxxxx>
Date: Wed, 14 Jul 2010 13:59:57 -0700
Accept-language: en-US
Acceptlanguage: en-US
Delivery-date: Wed, 14 Jul 2010 14:14:29 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acsjl4QhR77BSRkCRBC3W/+53/VlMw==
Thread-topic: [xen/stable-2.6.32.x PATCH 5/5] rtnetlink: make SR-IOV VF interface symmetric

Now we have a set of nested attributes:
   
  IFLA_VFINFO_LIST (NESTED)
    IFLA_VF_INFO (NESTED)
      IFLA_VF_MAC
      IFLA_VF_VLAN
      IFLA_VF_TX_RATE
   
This allows a single set to operate on multiple attributes if desired.
Among other things, it means a dump can be replayed to set state.
   
Signed-off-by: Greg Rose <gregory.v.rose@xxxxxxxxx>
CC: Chris Wright <chrisw@xxxxxxxxxxxx>

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index e77f2b4..d681cc9 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -82,10 +82,7 @@ enum
      IFLA_NET_NS_PID,
      IFLA_IFALIAS,
      IFLA_NUM_VF,            /* Number of VFs if device is SR-IOV PF */
-     IFLA_VF_MAC,            /* Hardware queue specific attributes */
-     IFLA_VF_VLAN,
-     IFLA_VF_TX_RATE,  /* TX Bandwidth Allocation */
-     IFLA_VFINFO,
+     IFLA_VFINFO_LIST,
      __IFLA_MAX
 };
 
@@ -197,6 +194,24 @@ struct ifla_vlan_qos_mapping
 
 /* SR-IOV virtual function managment section */
 
+enum {
+     IFLA_VF_INFO_UNSPEC,
+     IFLA_VF_INFO,
+     __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+     IFLA_VF_UNSPEC,
+     IFLA_VF_MAC,            /* Hardware queue specific attributes */
+     IFLA_VF_VLAN,
+     IFLA_VF_TX_RATE,  /* TX Bandwidth Allocation */
+     __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
 struct ifla_vf_mac {
      __u32 vf;
      __u8 mac[32]; /* MAX_ADDR_LEN */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b8541e4..f58325b 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -583,12 +583,18 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
      a->tx_compressed = b->tx_compressed;
 };
 
+/* All VF info */
 static inline int rtnl_vfinfo_size(const struct net_device *dev)
 {
-     if (dev->dev.parent && dev_is_pci(dev->dev.parent))
-           return dev_num_vf(dev->dev.parent) *
-                 sizeof(struct ifla_vf_info);
-     else
+     if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
+           int num_vfs = dev_num_vf(dev->dev.parent);
+           size_t size = nlmsg_total_size(sizeof(struct nlattr));
+           size += nlmsg_total_size(num_vfs * sizeof(struct nlattr));
+           size += num_vfs * (sizeof(struct ifla_vf_mac) +
+                         sizeof(struct ifla_vf_vlan) +
+                         sizeof(struct ifla_vf_tx_rate));
+           return size;
+     } else
            return 0;
 }
 
@@ -610,7 +616,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
             + nla_total_size(1) /* IFLA_OPERSTATE */
             + nla_total_size(1) /* IFLA_LINKMODE */
             + nla_total_size(4) /* IFLA_NUM_VF */
-            + nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */
+            + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
             + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
 }
 
@@ -681,14 +687,37 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 
      if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
            int i;
-           struct ifla_vf_info ivi;
 
-           NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
-           for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
+           struct nlattr *vfinfo, *vf;
+           int num_vfs = dev_num_vf(dev->dev.parent);
+
+           NLA_PUT_U32(skb, IFLA_NUM_VF, num_vfs);
+           vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
+           if (!vfinfo)
+                 goto nla_put_failure;
+           for (i = 0; i < num_vfs; i++) {
+                 struct ifla_vf_info ivi;
+                 struct ifla_vf_mac vf_mac;
+                 struct ifla_vf_vlan vf_vlan;
+                 struct ifla_vf_tx_rate vf_tx_rate;
                  if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
                        break;
-                 NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi);
+                 vf_mac.vf = vf_vlan.vf = vf_tx_rate.vf = ivi.vf;
+                 memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
+                 vf_vlan.vlan = ivi.vlan;
+                 vf_vlan.qos = ivi.qos;
+                 vf_tx_rate.rate = ivi.tx_rate;
+                 vf = nla_nest_start(skb, IFLA_VF_INFO);
+                 if (!vf) {
+                       nla_nest_cancel(skb, vfinfo);
+                       goto nla_put_failure;
+                 }
+                 NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
+                 NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan);
+                 NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), &vf_tx_rate);
+                 nla_nest_end(skb, vf);
            }
+           nla_nest_end(skb, vfinfo);
      }
      if (dev->rtnl_link_ops) {
            if (rtnl_link_fill(skb, dev) < 0)
@@ -739,6 +768,19 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
      [IFLA_LINKINFO]         = { .type = NLA_NESTED },
      [IFLA_NET_NS_PID] = { .type = NLA_U32 },
      [IFLA_IFALIAS]            = { .type = NLA_STRING, .len = IFALIASZ-1 },
+     [IFLA_VFINFO_LIST]      = {. type = NLA_NESTED },
+};
+
+static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
+     [IFLA_INFO_KIND]  = { .type = NLA_STRING },
+     [IFLA_INFO_DATA]  = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy ifla_vfinfo_policy[IFLA_VF_INFO_MAX+1] = {
+     [IFLA_VF_INFO]          = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
      [IFLA_VF_MAC]           = { .type = NLA_BINARY,
                            .len = sizeof(struct ifla_vf_mac) },
      [IFLA_VF_VLAN]          = { .type = NLA_BINARY,
@@ -747,11 +789,6 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
                            .len = sizeof(struct ifla_vf_tx_rate) },
 };
 
-static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
-     [IFLA_INFO_KIND]  = { .type = NLA_STRING },
-     [IFLA_INFO_DATA]  = { .type = NLA_NESTED },
-};
-
 static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
 {
      if (dev) {
@@ -767,6 +804,52 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
      return 0;
 }
 
+static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
+{
+     int rem, err = -EINVAL;
+     struct nlattr *vf;
+     const struct net_device_ops *ops = dev->netdev_ops;
+
+     nla_for_each_nested(vf, attr, rem) {
+           switch (nla_type(vf)) {
+           case IFLA_VF_MAC: {
+                 struct ifla_vf_mac *ivm;
+                 ivm = nla_data(vf);
+                 err = -EOPNOTSUPP;
+                 if (ops->ndo_set_vf_mac)
+                       err = ops->ndo_set_vf_mac(dev, ivm->vf,
+                                           ivm->mac);
+                 break;
+           }
+           case IFLA_VF_VLAN: {
+                 struct ifla_vf_vlan *ivv;
+                 ivv = nla_data(vf);
+                 err = -EOPNOTSUPP;
+                 if (ops->ndo_set_vf_vlan)
+                       err = ops->ndo_set_vf_vlan(dev, ivv->vf,
+                                            ivv->vlan,
+                                            ivv->qos);
+                 break;
+           }
+           case IFLA_VF_TX_RATE: {
+                 struct ifla_vf_tx_rate *ivt;
+                 ivt = nla_data(vf);
+                 err = -EOPNOTSUPP;
+                 if (ops->ndo_set_vf_tx_rate)
+                       err = ops->ndo_set_vf_tx_rate(dev, ivt->vf,
+                                               ivt->rate);
+                 break;
+           }
+           default:
+                 err = -EINVAL;
+                 break;
+           }
+           if (err)
+                 break;
+     }
+     return err;
+}
+
 static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                  struct nlattr **tb, char *ifname, int modified)
 {
@@ -904,43 +987,17 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
            write_unlock_bh(&dev_base_lock);
      }
 
-     if (tb[IFLA_VF_MAC]) {
-           struct ifla_vf_mac *ivm;
-           ivm = nla_data(tb[IFLA_VF_MAC]);
-           write_lock_bh(&dev_base_lock);
-           if (ops->ndo_set_vf_mac)
-                 err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac);
-           write_unlock_bh(&dev_base_lock);
-           if (err < 0)
-                 goto errout;
-           modified = 1;
-     }
-
-     if (tb[IFLA_VF_VLAN]) {
-           struct ifla_vf_vlan *ivv;
-           ivv = nla_data(tb[IFLA_VF_VLAN]);
-           write_lock_bh(&dev_base_lock);
-           if (ops->ndo_set_vf_vlan)
-                 err = ops->ndo_set_vf_vlan(dev, ivv->vf,
-                                      (u16)ivv->vlan,
-                                      (u8)ivv->qos);
-           write_unlock_bh(&dev_base_lock);
-           if (err < 0)
-                 goto errout;
-           modified = 1;
-     }
-     err = 0;
-
-     if (tb[IFLA_VF_TX_RATE]) {
-           struct ifla_vf_tx_rate *ivt;
-           ivt = nla_data(tb[IFLA_VF_TX_RATE]);
-           write_lock_bh(&dev_base_lock);
-           if (ops->ndo_set_vf_tx_rate)
-                 err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate);
-           write_unlock_bh(&dev_base_lock);
-           if (err < 0)
-                 goto errout;
-           modified = 1;
+     if (tb[IFLA_VFINFO_LIST]) {
+           struct nlattr *attr;
+           int rem;
+           nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) {
+                 if (nla_type(attr) != IFLA_VF_INFO)
+                       goto errout;
+                 err = do_setvfinfo(dev, attr);
+                 if (err < 0)
+                       goto errout;
+                 modified = 1;
+           }
      }
      err = 0;
 

 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [xen/stable-2.6.32.x PATCH 5/5] rtnetlink: make SR-IOV VF interface symmetric, Rose, Gregory V <=