aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 13:01:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 13:01:50 -0400
commit3c4cfadef6a1665d9cd02a543782d03d3e6740c6 (patch)
tree3df72faaacd494d5ac8c9668df4f529b1b5e4457 /drivers/infiniband
parente017507f37d5cb8b541df165a824958bc333bec3 (diff)
parent320f5ea0cedc08ef65d67e056bcb9d181386ef2c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David S Miller: 1) Remove the ipv4 routing cache. Now lookups go directly into the FIB trie and use prebuilt routes cached there. No more garbage collection, no more rDOS attacks on the routing cache. Instead we now get predictable and consistent performance, no matter what the pattern of traffic we service. This has been almost 2 years in the making. Special thanks to Julian Anastasov, Eric Dumazet, Steffen Klassert, and others who have helped along the way. I'm sure that with a change of this magnitude there will be some kind of fallout, but such things ought the be simple to fix at this point. Luckily I'm not European so I'll be around all of August to fix things :-) The major stages of this work here are each fronted by a forced merge commit whose commit message contains a top-level description of the motivations and implementation issues. 2) Pre-demux of established ipv4 TCP sockets, saves a route demux on input. 3) TCP SYN/ACK performance tweaks from Eric Dumazet. 4) Add namespace support for netfilter L4 conntrack helpers, from Gao Feng. 5) Add config mechanism for Energy Efficient Ethernet to ethtool, from Yuval Mintz. 6) Remove quadratic behavior from /proc/net/unix, from Eric Dumazet. 7) Support for connection tracker helpers in userspace, from Pablo Neira Ayuso. 8) Allow userspace driven TX load balancing functions in TEAM driver, from Jiri Pirko. 9) Kill off NLMSG_PUT and RTA_PUT macros, more gross stuff with embedded gotos. 10) TCP Small Queues, essentially minimize the amount of TCP data queued up in the packet scheduler layer. Whereas the existing BQL (Byte Queue Limits) limits the pkt_sched --> netdevice queuing levels, this controls the TCP --> pkt_sched queueing levels. From Eric Dumazet. 11) Reduce the number of get_page/put_page ops done on SKB fragments, from Alexander Duyck. 12) Implement protection against blind resets in TCP (RFC 5961), from Eric Dumazet. 13) Support the client side of TCP Fast Open, basically the ability to send data in the SYN exchange, from Yuchung Cheng. Basically, the sender queues up data with a sendmsg() call using MSG_FASTOPEN, then they do the connect() which emits the queued up fastopen data. 14) Avoid all the problems we get into in TCP when timers or PMTU events hit a locked socket. The TCP Small Queues changes added a tcp_release_cb() that allows us to queue work up to the release_sock() caller, and that's what we use here too. From Eric Dumazet. 15) Zero copy on TX support for TUN driver, from Michael S. Tsirkin. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1870 commits) genetlink: define lockdep_genl_is_held() when CONFIG_LOCKDEP r8169: revert "add byte queue limit support". ipv4: Change rt->rt_iif encoding. net: Make skb->skb_iif always track skb->dev ipv4: Prepare for change of rt->rt_iif encoding. ipv4: Remove all RTCF_DIRECTSRC handliing. ipv4: Really ignore ICMP address requests/replies. decnet: Don't set RTCF_DIRECTSRC. net/ipv4/ip_vti.c: Fix __rcu warnings detected by sparse. ipv4: Remove redundant assignment rds: set correct msg_namelen openvswitch: potential NULL deref in sample() tcp: dont drop MTU reduction indications bnx2x: Add new 57840 device IDs tcp: avoid oops in tcp_metrics and reset tcpm_stamp niu: Change niu_rbr_fill() to use unlikely() to check niu_rbr_add_page() return value niu: Fix to check for dma mapping errors. net: Fix references to out-of-scope variables in put_cmsg_compat() net: ethernet: davinci_emac: add pm_runtime support net: ethernet: davinci_emac: Remove unnecessary #include ...
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/netlink.c17
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c5
-rw-r--r--drivers/infiniband/hw/mlx4/main.c65
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h1
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c35
8 files changed, 97 insertions, 33 deletions
diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c
index e497dfbee435..3ae2bfd31015 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -108,12 +108,14 @@ void *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq,
108 unsigned char *prev_tail; 108 unsigned char *prev_tail;
109 109
110 prev_tail = skb_tail_pointer(skb); 110 prev_tail = skb_tail_pointer(skb);
111 *nlh = NLMSG_NEW(skb, 0, seq, RDMA_NL_GET_TYPE(client, op), 111 *nlh = nlmsg_put(skb, 0, seq, RDMA_NL_GET_TYPE(client, op),
112 len, NLM_F_MULTI); 112 len, NLM_F_MULTI);
113 if (!*nlh)
114 goto out_nlmsg_trim;
113 (*nlh)->nlmsg_len = skb_tail_pointer(skb) - prev_tail; 115 (*nlh)->nlmsg_len = skb_tail_pointer(skb) - prev_tail;
114 return NLMSG_DATA(*nlh); 116 return nlmsg_data(*nlh);
115 117
116nlmsg_failure: 118out_nlmsg_trim:
117 nlmsg_trim(skb, prev_tail); 119 nlmsg_trim(skb, prev_tail);
118 return NULL; 120 return NULL;
119} 121}
@@ -171,8 +173,11 @@ static void ibnl_rcv(struct sk_buff *skb)
171 173
172int __init ibnl_init(void) 174int __init ibnl_init(void)
173{ 175{
174 nls = netlink_kernel_create(&init_net, NETLINK_RDMA, 0, ibnl_rcv, 176 struct netlink_kernel_cfg cfg = {
175 NULL, THIS_MODULE); 177 .input = ibnl_rcv,
178 };
179
180 nls = netlink_kernel_create(&init_net, NETLINK_RDMA, THIS_MODULE, &cfg);
176 if (!nls) { 181 if (!nls) {
177 pr_warn("Failed to create netlink socket\n"); 182 pr_warn("Failed to create netlink socket\n");
178 return -ENOMEM; 183 return -ENOMEM;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 740dcc065cf2..77b6b182778a 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1374,7 +1374,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
1374 goto reject; 1374 goto reject;
1375 } 1375 }
1376 dst = &rt->dst; 1376 dst = &rt->dst;
1377 l2t = t3_l2t_get(tdev, dst, NULL); 1377 l2t = t3_l2t_get(tdev, dst, NULL, &req->peer_ip);
1378 if (!l2t) { 1378 if (!l2t) {
1379 printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n", 1379 printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
1380 __func__); 1380 __func__);
@@ -1942,7 +1942,8 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
1942 goto fail3; 1942 goto fail3;
1943 } 1943 }
1944 ep->dst = &rt->dst; 1944 ep->dst = &rt->dst;
1945 ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst, NULL); 1945 ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst, NULL,
1946 &cm_id->remote_addr.sin_addr.s_addr);
1946 if (!ep->l2t) { 1947 if (!ep->l2t) {
1947 printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__); 1948 printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
1948 err = -ENOMEM; 1949 err = -ENOMEM;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 3530c41fcd1f..a07b774e7864 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -718,26 +718,53 @@ int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
718 return ret; 718 return ret;
719} 719}
720 720
721struct mlx4_ib_steering {
722 struct list_head list;
723 u64 reg_id;
724 union ib_gid gid;
725};
726
721static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) 727static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
722{ 728{
723 int err; 729 int err;
724 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); 730 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
725 struct mlx4_ib_qp *mqp = to_mqp(ibqp); 731 struct mlx4_ib_qp *mqp = to_mqp(ibqp);
732 u64 reg_id;
733 struct mlx4_ib_steering *ib_steering = NULL;
734
735 if (mdev->dev->caps.steering_mode ==
736 MLX4_STEERING_MODE_DEVICE_MANAGED) {
737 ib_steering = kmalloc(sizeof(*ib_steering), GFP_KERNEL);
738 if (!ib_steering)
739 return -ENOMEM;
740 }
726 741
727 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, 742 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, mqp->port,
728 !!(mqp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK), 743 !!(mqp->flags &
729 MLX4_PROT_IB_IPV6); 744 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
745 MLX4_PROT_IB_IPV6, &reg_id);
730 if (err) 746 if (err)
731 return err; 747 goto err_malloc;
732 748
733 err = add_gid_entry(ibqp, gid); 749 err = add_gid_entry(ibqp, gid);
734 if (err) 750 if (err)
735 goto err_add; 751 goto err_add;
736 752
753 if (ib_steering) {
754 memcpy(ib_steering->gid.raw, gid->raw, 16);
755 ib_steering->reg_id = reg_id;
756 mutex_lock(&mqp->mutex);
757 list_add(&ib_steering->list, &mqp->steering_rules);
758 mutex_unlock(&mqp->mutex);
759 }
737 return 0; 760 return 0;
738 761
739err_add: 762err_add:
740 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROT_IB_IPV6); 763 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw,
764 MLX4_PROT_IB_IPV6, reg_id);
765err_malloc:
766 kfree(ib_steering);
767
741 return err; 768 return err;
742} 769}
743 770
@@ -765,9 +792,30 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
765 u8 mac[6]; 792 u8 mac[6];
766 struct net_device *ndev; 793 struct net_device *ndev;
767 struct mlx4_ib_gid_entry *ge; 794 struct mlx4_ib_gid_entry *ge;
795 u64 reg_id = 0;
796
797 if (mdev->dev->caps.steering_mode ==
798 MLX4_STEERING_MODE_DEVICE_MANAGED) {
799 struct mlx4_ib_steering *ib_steering;
800
801 mutex_lock(&mqp->mutex);
802 list_for_each_entry(ib_steering, &mqp->steering_rules, list) {
803 if (!memcmp(ib_steering->gid.raw, gid->raw, 16)) {
804 list_del(&ib_steering->list);
805 break;
806 }
807 }
808 mutex_unlock(&mqp->mutex);
809 if (&ib_steering->list == &mqp->steering_rules) {
810 pr_err("Couldn't find reg_id for mgid. Steering rule is left attached\n");
811 return -EINVAL;
812 }
813 reg_id = ib_steering->reg_id;
814 kfree(ib_steering);
815 }
768 816
769 err = mlx4_multicast_detach(mdev->dev, 817 err = mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw,
770 &mqp->mqp, gid->raw, MLX4_PROT_IB_IPV6); 818 MLX4_PROT_IB_IPV6, reg_id);
771 if (err) 819 if (err)
772 return err; 820 return err;
773 821
@@ -1111,7 +1159,8 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
1111 sprintf(name, "mlx4-ib-%d-%d@%s", 1159 sprintf(name, "mlx4-ib-%d-%d@%s",
1112 i, j, dev->pdev->bus->name); 1160 i, j, dev->pdev->bus->name);
1113 /* Set IRQ for specific name (per ring) */ 1161 /* Set IRQ for specific name (per ring) */
1114 if (mlx4_assign_eq(dev, name, &ibdev->eq_table[eq])) { 1162 if (mlx4_assign_eq(dev, name, NULL,
1163 &ibdev->eq_table[eq])) {
1115 /* Use legacy (same as mlx4_en driver) */ 1164 /* Use legacy (same as mlx4_en driver) */
1116 pr_warn("Can't allocate EQ %d; reverting to legacy\n", eq); 1165 pr_warn("Can't allocate EQ %d; reverting to legacy\n", eq);
1117 ibdev->eq_table[eq] = 1166 ibdev->eq_table[eq] =
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index ff36655d23d3..42df4f7a6a5b 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -163,6 +163,7 @@ struct mlx4_ib_qp {
163 u8 state; 163 u8 state;
164 int mlx_type; 164 int mlx_type;
165 struct list_head gid_list; 165 struct list_head gid_list;
166 struct list_head steering_rules;
166}; 167};
167 168
168struct mlx4_ib_srq { 169struct mlx4_ib_srq {
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 8d4ed24aef93..6af19f6c2b11 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -495,6 +495,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
495 spin_lock_init(&qp->sq.lock); 495 spin_lock_init(&qp->sq.lock);
496 spin_lock_init(&qp->rq.lock); 496 spin_lock_init(&qp->rq.lock);
497 INIT_LIST_HEAD(&qp->gid_list); 497 INIT_LIST_HEAD(&qp->gid_list);
498 INIT_LIST_HEAD(&qp->steering_rules);
498 499
499 qp->state = IB_QPS_RESET; 500 qp->state = IB_QPS_RESET;
500 if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) 501 if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 014504d8e43c..1ca732201f33 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1397,7 +1397,7 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
1397 int e = skb_queue_empty(&priv->cm.skb_queue); 1397 int e = skb_queue_empty(&priv->cm.skb_queue);
1398 1398
1399 if (skb_dst(skb)) 1399 if (skb_dst(skb))
1400 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); 1400 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
1401 1401
1402 skb_queue_tail(&priv->cm.skb_queue, skb); 1402 skb_queue_tail(&priv->cm.skb_queue, skb);
1403 if (e) 1403 if (e)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 3974c290b667..bbee4b2d7a13 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -715,7 +715,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
715 715
716 rcu_read_lock(); 716 rcu_read_lock();
717 if (likely(skb_dst(skb))) { 717 if (likely(skb_dst(skb))) {
718 n = dst_get_neighbour_noref(skb_dst(skb)); 718 n = dst_neigh_lookup_skb(skb_dst(skb), skb);
719 if (!n) { 719 if (!n) {
720 ++dev->stats.tx_dropped; 720 ++dev->stats.tx_dropped;
721 dev_kfree_skb_any(skb); 721 dev_kfree_skb_any(skb);
@@ -797,6 +797,8 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
797 } 797 }
798 } 798 }
799unlock: 799unlock:
800 if (n)
801 neigh_release(n);
800 rcu_read_unlock(); 802 rcu_read_unlock();
801 return NETDEV_TX_OK; 803 return NETDEV_TX_OK;
802} 804}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 20ebc6fd1bb9..7cecb16d3d48 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -658,9 +658,15 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
658void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) 658void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
659{ 659{
660 struct ipoib_dev_priv *priv = netdev_priv(dev); 660 struct ipoib_dev_priv *priv = netdev_priv(dev);
661 struct dst_entry *dst = skb_dst(skb);
661 struct ipoib_mcast *mcast; 662 struct ipoib_mcast *mcast;
663 struct neighbour *n;
662 unsigned long flags; 664 unsigned long flags;
663 665
666 n = NULL;
667 if (dst)
668 n = dst_neigh_lookup_skb(dst, skb);
669
664 spin_lock_irqsave(&priv->lock, flags); 670 spin_lock_irqsave(&priv->lock, flags);
665 671
666 if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) || 672 if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) ||
@@ -715,29 +721,28 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
715 721
716out: 722out:
717 if (mcast && mcast->ah) { 723 if (mcast && mcast->ah) {
718 struct dst_entry *dst = skb_dst(skb); 724 if (n) {
719 struct neighbour *n = NULL; 725 if (!*to_ipoib_neigh(n)) {
720 726 struct ipoib_neigh *neigh;
721 rcu_read_lock(); 727
722 if (dst) 728 neigh = ipoib_neigh_alloc(n, skb->dev);
723 n = dst_get_neighbour_noref(dst); 729 if (neigh) {
724 if (n && !*to_ipoib_neigh(n)) { 730 kref_get(&mcast->ah->ref);
725 struct ipoib_neigh *neigh = ipoib_neigh_alloc(n, 731 neigh->ah = mcast->ah;
726 skb->dev); 732 list_add_tail(&neigh->list,
727 733 &mcast->neigh_list);
728 if (neigh) { 734 }
729 kref_get(&mcast->ah->ref);
730 neigh->ah = mcast->ah;
731 list_add_tail(&neigh->list, &mcast->neigh_list);
732 } 735 }
736 neigh_release(n);
733 } 737 }
734 rcu_read_unlock();
735 spin_unlock_irqrestore(&priv->lock, flags); 738 spin_unlock_irqrestore(&priv->lock, flags);
736 ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); 739 ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
737 return; 740 return;
738 } 741 }
739 742
740unlock: 743unlock:
744 if (n)
745 neigh_release(n);
741 spin_unlock_irqrestore(&priv->lock, flags); 746 spin_unlock_irqrestore(&priv->lock, flags);
742} 747}
743 748