aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/veth.c70
1 files changed, 33 insertions, 37 deletions
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index e3202af72df5..8d679c8b7f25 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -789,16 +789,48 @@ static int is_valid_veth_mtu(int mtu)
789 return mtu >= ETH_MIN_MTU && mtu <= ETH_MAX_MTU; 789 return mtu >= ETH_MIN_MTU && mtu <= ETH_MAX_MTU;
790} 790}
791 791
792static int veth_alloc_queues(struct net_device *dev)
793{
794 struct veth_priv *priv = netdev_priv(dev);
795 int i;
796
797 priv->rq = kcalloc(dev->num_rx_queues, sizeof(*priv->rq), GFP_KERNEL);
798 if (!priv->rq)
799 return -ENOMEM;
800
801 for (i = 0; i < dev->num_rx_queues; i++)
802 priv->rq[i].dev = dev;
803
804 return 0;
805}
806
807static void veth_free_queues(struct net_device *dev)
808{
809 struct veth_priv *priv = netdev_priv(dev);
810
811 kfree(priv->rq);
812}
813
792static int veth_dev_init(struct net_device *dev) 814static int veth_dev_init(struct net_device *dev)
793{ 815{
816 int err;
817
794 dev->vstats = netdev_alloc_pcpu_stats(struct pcpu_vstats); 818 dev->vstats = netdev_alloc_pcpu_stats(struct pcpu_vstats);
795 if (!dev->vstats) 819 if (!dev->vstats)
796 return -ENOMEM; 820 return -ENOMEM;
821
822 err = veth_alloc_queues(dev);
823 if (err) {
824 free_percpu(dev->vstats);
825 return err;
826 }
827
797 return 0; 828 return 0;
798} 829}
799 830
800static void veth_dev_free(struct net_device *dev) 831static void veth_dev_free(struct net_device *dev)
801{ 832{
833 veth_free_queues(dev);
802 free_percpu(dev->vstats); 834 free_percpu(dev->vstats);
803} 835}
804 836
@@ -1040,31 +1072,13 @@ static int veth_validate(struct nlattr *tb[], struct nlattr *data[],
1040 return 0; 1072 return 0;
1041} 1073}
1042 1074
1043static int veth_alloc_queues(struct net_device *dev)
1044{
1045 struct veth_priv *priv = netdev_priv(dev);
1046
1047 priv->rq = kcalloc(dev->num_rx_queues, sizeof(*priv->rq), GFP_KERNEL);
1048 if (!priv->rq)
1049 return -ENOMEM;
1050
1051 return 0;
1052}
1053
1054static void veth_free_queues(struct net_device *dev)
1055{
1056 struct veth_priv *priv = netdev_priv(dev);
1057
1058 kfree(priv->rq);
1059}
1060
1061static struct rtnl_link_ops veth_link_ops; 1075static struct rtnl_link_ops veth_link_ops;
1062 1076
1063static int veth_newlink(struct net *src_net, struct net_device *dev, 1077static int veth_newlink(struct net *src_net, struct net_device *dev,
1064 struct nlattr *tb[], struct nlattr *data[], 1078 struct nlattr *tb[], struct nlattr *data[],
1065 struct netlink_ext_ack *extack) 1079 struct netlink_ext_ack *extack)
1066{ 1080{
1067 int err, i; 1081 int err;
1068 struct net_device *peer; 1082 struct net_device *peer;
1069 struct veth_priv *priv; 1083 struct veth_priv *priv;
1070 char ifname[IFNAMSIZ]; 1084 char ifname[IFNAMSIZ];
@@ -1117,12 +1131,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
1117 return PTR_ERR(peer); 1131 return PTR_ERR(peer);
1118 } 1132 }
1119 1133
1120 err = veth_alloc_queues(peer);
1121 if (err) {
1122 put_net(net);
1123 goto err_peer_alloc_queues;
1124 }
1125
1126 if (!ifmp || !tbp[IFLA_ADDRESS]) 1134 if (!ifmp || !tbp[IFLA_ADDRESS])
1127 eth_hw_addr_random(peer); 1135 eth_hw_addr_random(peer);
1128 1136
@@ -1151,10 +1159,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
1151 * should be re-allocated 1159 * should be re-allocated
1152 */ 1160 */
1153 1161
1154 err = veth_alloc_queues(dev);
1155 if (err)
1156 goto err_alloc_queues;
1157
1158 if (tb[IFLA_ADDRESS] == NULL) 1162 if (tb[IFLA_ADDRESS] == NULL)
1159 eth_hw_addr_random(dev); 1163 eth_hw_addr_random(dev);
1160 1164
@@ -1174,28 +1178,20 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
1174 */ 1178 */
1175 1179
1176 priv = netdev_priv(dev); 1180 priv = netdev_priv(dev);
1177 for (i = 0; i < dev->real_num_rx_queues; i++)
1178 priv->rq[i].dev = dev;
1179 rcu_assign_pointer(priv->peer, peer); 1181 rcu_assign_pointer(priv->peer, peer);
1180 1182
1181 priv = netdev_priv(peer); 1183 priv = netdev_priv(peer);
1182 for (i = 0; i < peer->real_num_rx_queues; i++)
1183 priv->rq[i].dev = peer;
1184 rcu_assign_pointer(priv->peer, dev); 1184 rcu_assign_pointer(priv->peer, dev);
1185 1185
1186 return 0; 1186 return 0;
1187 1187
1188err_register_dev: 1188err_register_dev:
1189 veth_free_queues(dev);
1190err_alloc_queues:
1191 /* nothing to do */ 1189 /* nothing to do */
1192err_configure_peer: 1190err_configure_peer:
1193 unregister_netdevice(peer); 1191 unregister_netdevice(peer);
1194 return err; 1192 return err;
1195 1193
1196err_register_peer: 1194err_register_peer:
1197 veth_free_queues(peer);
1198err_peer_alloc_queues:
1199 free_netdev(peer); 1195 free_netdev(peer);
1200 return err; 1196 return err;
1201} 1197}