diff options
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/Kconfig | 3 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 7 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_fs.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 22 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 88 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 58 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 19 |
8 files changed, 116 insertions, 89 deletions
diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig index 8d2e04cac68e..13d6d01c72c0 100644 --- a/drivers/infiniband/ulp/ipoib/Kconfig +++ b/drivers/infiniband/ulp/ipoib/Kconfig | |||
@@ -10,8 +10,9 @@ config INFINIBAND_IPOIB | |||
10 | group: <http://www.ietf.org/html.charters/ipoib-charter.html>. | 10 | group: <http://www.ietf.org/html.charters/ipoib-charter.html>. |
11 | 11 | ||
12 | config INFINIBAND_IPOIB_DEBUG | 12 | config INFINIBAND_IPOIB_DEBUG |
13 | bool "IP-over-InfiniBand debugging" | 13 | bool "IP-over-InfiniBand debugging" if EMBEDDED |
14 | depends on INFINIBAND_IPOIB | 14 | depends on INFINIBAND_IPOIB |
15 | default y | ||
15 | ---help--- | 16 | ---help--- |
16 | This option causes debugging code to be compiled into the | 17 | This option causes debugging code to be compiled into the |
17 | IPoIB driver. The output can be turned on via the | 18 | IPoIB driver. The output can be turned on via the |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index b640107fb732..12a1e0572ef2 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -65,6 +65,8 @@ enum { | |||
65 | 65 | ||
66 | IPOIB_RX_RING_SIZE = 128, | 66 | IPOIB_RX_RING_SIZE = 128, |
67 | IPOIB_TX_RING_SIZE = 64, | 67 | IPOIB_TX_RING_SIZE = 64, |
68 | IPOIB_MAX_QUEUE_SIZE = 8192, | ||
69 | IPOIB_MIN_QUEUE_SIZE = 2, | ||
68 | 70 | ||
69 | IPOIB_NUM_WC = 4, | 71 | IPOIB_NUM_WC = 4, |
70 | 72 | ||
@@ -230,6 +232,9 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh) | |||
230 | INFINIBAND_ALEN, sizeof(void *)); | 232 | INFINIBAND_ALEN, sizeof(void *)); |
231 | } | 233 | } |
232 | 234 | ||
235 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh); | ||
236 | void ipoib_neigh_free(struct ipoib_neigh *neigh); | ||
237 | |||
233 | extern struct workqueue_struct *ipoib_workqueue; | 238 | extern struct workqueue_struct *ipoib_workqueue; |
234 | 239 | ||
235 | /* functions */ | 240 | /* functions */ |
@@ -329,6 +334,8 @@ static inline void ipoib_unregister_debugfs(void) { } | |||
329 | #define ipoib_warn(priv, format, arg...) \ | 334 | #define ipoib_warn(priv, format, arg...) \ |
330 | ipoib_printk(KERN_WARNING, priv, format , ## arg) | 335 | ipoib_printk(KERN_WARNING, priv, format , ## arg) |
331 | 336 | ||
337 | extern int ipoib_sendq_size; | ||
338 | extern int ipoib_recvq_size; | ||
332 | 339 | ||
333 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 340 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
334 | extern int ipoib_debug_level; | 341 | extern int ipoib_debug_level; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 685258e34034..5dde380e8dbe 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
@@ -213,7 +213,7 @@ static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr) | |||
213 | gid_buf, path.pathrec.dlid ? "yes" : "no"); | 213 | gid_buf, path.pathrec.dlid ? "yes" : "no"); |
214 | 214 | ||
215 | if (path.pathrec.dlid) { | 215 | if (path.pathrec.dlid) { |
216 | rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25; | 216 | rate = ib_rate_to_mult(path.pathrec.rate) * 25; |
217 | 217 | ||
218 | seq_printf(file, | 218 | seq_printf(file, |
219 | " DLID: 0x%04x\n" | 219 | " DLID: 0x%04x\n" |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index ed65202878d8..a54da42849ae 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -161,7 +161,7 @@ static int ipoib_ib_post_receives(struct net_device *dev) | |||
161 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 161 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
162 | int i; | 162 | int i; |
163 | 163 | ||
164 | for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) { | 164 | for (i = 0; i < ipoib_recvq_size; ++i) { |
165 | if (ipoib_alloc_rx_skb(dev, i)) { | 165 | if (ipoib_alloc_rx_skb(dev, i)) { |
166 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); | 166 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); |
167 | return -ENOMEM; | 167 | return -ENOMEM; |
@@ -187,7 +187,7 @@ static void ipoib_ib_handle_wc(struct net_device *dev, | |||
187 | if (wr_id & IPOIB_OP_RECV) { | 187 | if (wr_id & IPOIB_OP_RECV) { |
188 | wr_id &= ~IPOIB_OP_RECV; | 188 | wr_id &= ~IPOIB_OP_RECV; |
189 | 189 | ||
190 | if (wr_id < IPOIB_RX_RING_SIZE) { | 190 | if (wr_id < ipoib_recvq_size) { |
191 | struct sk_buff *skb = priv->rx_ring[wr_id].skb; | 191 | struct sk_buff *skb = priv->rx_ring[wr_id].skb; |
192 | dma_addr_t addr = priv->rx_ring[wr_id].mapping; | 192 | dma_addr_t addr = priv->rx_ring[wr_id].mapping; |
193 | 193 | ||
@@ -252,9 +252,9 @@ static void ipoib_ib_handle_wc(struct net_device *dev, | |||
252 | struct ipoib_tx_buf *tx_req; | 252 | struct ipoib_tx_buf *tx_req; |
253 | unsigned long flags; | 253 | unsigned long flags; |
254 | 254 | ||
255 | if (wr_id >= IPOIB_TX_RING_SIZE) { | 255 | if (wr_id >= ipoib_sendq_size) { |
256 | ipoib_warn(priv, "completion event with wrid %d (> %d)\n", | 256 | ipoib_warn(priv, "completion event with wrid %d (> %d)\n", |
257 | wr_id, IPOIB_TX_RING_SIZE); | 257 | wr_id, ipoib_sendq_size); |
258 | return; | 258 | return; |
259 | } | 259 | } |
260 | 260 | ||
@@ -275,7 +275,7 @@ static void ipoib_ib_handle_wc(struct net_device *dev, | |||
275 | spin_lock_irqsave(&priv->tx_lock, flags); | 275 | spin_lock_irqsave(&priv->tx_lock, flags); |
276 | ++priv->tx_tail; | 276 | ++priv->tx_tail; |
277 | if (netif_queue_stopped(dev) && | 277 | if (netif_queue_stopped(dev) && |
278 | priv->tx_head - priv->tx_tail <= IPOIB_TX_RING_SIZE / 2) | 278 | priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1) |
279 | netif_wake_queue(dev); | 279 | netif_wake_queue(dev); |
280 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 280 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
281 | 281 | ||
@@ -344,13 +344,13 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
344 | * means we have to make sure everything is properly recorded and | 344 | * means we have to make sure everything is properly recorded and |
345 | * our state is consistent before we call post_send(). | 345 | * our state is consistent before we call post_send(). |
346 | */ | 346 | */ |
347 | tx_req = &priv->tx_ring[priv->tx_head & (IPOIB_TX_RING_SIZE - 1)]; | 347 | tx_req = &priv->tx_ring[priv->tx_head & (ipoib_sendq_size - 1)]; |
348 | tx_req->skb = skb; | 348 | tx_req->skb = skb; |
349 | addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len, | 349 | addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len, |
350 | DMA_TO_DEVICE); | 350 | DMA_TO_DEVICE); |
351 | pci_unmap_addr_set(tx_req, mapping, addr); | 351 | pci_unmap_addr_set(tx_req, mapping, addr); |
352 | 352 | ||
353 | if (unlikely(post_send(priv, priv->tx_head & (IPOIB_TX_RING_SIZE - 1), | 353 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
354 | address->ah, qpn, addr, skb->len))) { | 354 | address->ah, qpn, addr, skb->len))) { |
355 | ipoib_warn(priv, "post_send failed\n"); | 355 | ipoib_warn(priv, "post_send failed\n"); |
356 | ++priv->stats.tx_errors; | 356 | ++priv->stats.tx_errors; |
@@ -363,7 +363,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
363 | address->last_send = priv->tx_head; | 363 | address->last_send = priv->tx_head; |
364 | ++priv->tx_head; | 364 | ++priv->tx_head; |
365 | 365 | ||
366 | if (priv->tx_head - priv->tx_tail == IPOIB_TX_RING_SIZE) { | 366 | if (priv->tx_head - priv->tx_tail == ipoib_sendq_size) { |
367 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); | 367 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); |
368 | netif_stop_queue(dev); | 368 | netif_stop_queue(dev); |
369 | } | 369 | } |
@@ -488,7 +488,7 @@ static int recvs_pending(struct net_device *dev) | |||
488 | int pending = 0; | 488 | int pending = 0; |
489 | int i; | 489 | int i; |
490 | 490 | ||
491 | for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) | 491 | for (i = 0; i < ipoib_recvq_size; ++i) |
492 | if (priv->rx_ring[i].skb) | 492 | if (priv->rx_ring[i].skb) |
493 | ++pending; | 493 | ++pending; |
494 | 494 | ||
@@ -527,7 +527,7 @@ int ipoib_ib_dev_stop(struct net_device *dev) | |||
527 | */ | 527 | */ |
528 | while ((int) priv->tx_tail - (int) priv->tx_head < 0) { | 528 | while ((int) priv->tx_tail - (int) priv->tx_head < 0) { |
529 | tx_req = &priv->tx_ring[priv->tx_tail & | 529 | tx_req = &priv->tx_ring[priv->tx_tail & |
530 | (IPOIB_TX_RING_SIZE - 1)]; | 530 | (ipoib_sendq_size - 1)]; |
531 | dma_unmap_single(priv->ca->dma_device, | 531 | dma_unmap_single(priv->ca->dma_device, |
532 | pci_unmap_addr(tx_req, mapping), | 532 | pci_unmap_addr(tx_req, mapping), |
533 | tx_req->skb->len, | 533 | tx_req->skb->len, |
@@ -536,7 +536,7 @@ int ipoib_ib_dev_stop(struct net_device *dev) | |||
536 | ++priv->tx_tail; | 536 | ++priv->tx_tail; |
537 | } | 537 | } |
538 | 538 | ||
539 | for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) | 539 | for (i = 0; i < ipoib_recvq_size; ++i) |
540 | if (priv->rx_ring[i].skb) { | 540 | if (priv->rx_ring[i].skb) { |
541 | dma_unmap_single(priv->ca->dma_device, | 541 | dma_unmap_single(priv->ca->dma_device, |
542 | pci_unmap_addr(&priv->rx_ring[i], | 542 | pci_unmap_addr(&priv->rx_ring[i], |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 9b0bd7c746ca..cb078a7d0bf5 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/vmalloc.h> | 43 | #include <linux/vmalloc.h> |
44 | #include <linux/kernel.h> | ||
44 | 45 | ||
45 | #include <linux/if_arp.h> /* For ARPHRD_xxx */ | 46 | #include <linux/if_arp.h> /* For ARPHRD_xxx */ |
46 | 47 | ||
@@ -53,6 +54,14 @@ MODULE_AUTHOR("Roland Dreier"); | |||
53 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); | 54 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); |
54 | MODULE_LICENSE("Dual BSD/GPL"); | 55 | MODULE_LICENSE("Dual BSD/GPL"); |
55 | 56 | ||
57 | int ipoib_sendq_size __read_mostly = IPOIB_TX_RING_SIZE; | ||
58 | int ipoib_recvq_size __read_mostly = IPOIB_RX_RING_SIZE; | ||
59 | |||
60 | module_param_named(send_queue_size, ipoib_sendq_size, int, 0444); | ||
61 | MODULE_PARM_DESC(send_queue_size, "Number of descriptors in send queue"); | ||
62 | module_param_named(recv_queue_size, ipoib_recvq_size, int, 0444); | ||
63 | MODULE_PARM_DESC(recv_queue_size, "Number of descriptors in receive queue"); | ||
64 | |||
56 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 65 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
57 | int ipoib_debug_level; | 66 | int ipoib_debug_level; |
58 | 67 | ||
@@ -252,8 +261,8 @@ static void path_free(struct net_device *dev, struct ipoib_path *path) | |||
252 | */ | 261 | */ |
253 | if (neigh->ah) | 262 | if (neigh->ah) |
254 | ipoib_put_ah(neigh->ah); | 263 | ipoib_put_ah(neigh->ah); |
255 | *to_ipoib_neigh(neigh->neighbour) = NULL; | 264 | |
256 | kfree(neigh); | 265 | ipoib_neigh_free(neigh); |
257 | } | 266 | } |
258 | 267 | ||
259 | spin_unlock_irqrestore(&priv->lock, flags); | 268 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -327,9 +336,8 @@ void ipoib_flush_paths(struct net_device *dev) | |||
327 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 336 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
328 | struct ipoib_path *path, *tp; | 337 | struct ipoib_path *path, *tp; |
329 | LIST_HEAD(remove_list); | 338 | LIST_HEAD(remove_list); |
330 | unsigned long flags; | ||
331 | 339 | ||
332 | spin_lock_irqsave(&priv->lock, flags); | 340 | spin_lock_irq(&priv->lock); |
333 | 341 | ||
334 | list_splice(&priv->path_list, &remove_list); | 342 | list_splice(&priv->path_list, &remove_list); |
335 | INIT_LIST_HEAD(&priv->path_list); | 343 | INIT_LIST_HEAD(&priv->path_list); |
@@ -337,14 +345,15 @@ void ipoib_flush_paths(struct net_device *dev) | |||
337 | list_for_each_entry(path, &remove_list, list) | 345 | list_for_each_entry(path, &remove_list, list) |
338 | rb_erase(&path->rb_node, &priv->path_tree); | 346 | rb_erase(&path->rb_node, &priv->path_tree); |
339 | 347 | ||
340 | spin_unlock_irqrestore(&priv->lock, flags); | ||
341 | |||
342 | list_for_each_entry_safe(path, tp, &remove_list, list) { | 348 | list_for_each_entry_safe(path, tp, &remove_list, list) { |
343 | if (path->query) | 349 | if (path->query) |
344 | ib_sa_cancel_query(path->query_id, path->query); | 350 | ib_sa_cancel_query(path->query_id, path->query); |
351 | spin_unlock_irq(&priv->lock); | ||
345 | wait_for_completion(&path->done); | 352 | wait_for_completion(&path->done); |
346 | path_free(dev, path); | 353 | path_free(dev, path); |
354 | spin_lock_irq(&priv->lock); | ||
347 | } | 355 | } |
356 | spin_unlock_irq(&priv->lock); | ||
348 | } | 357 | } |
349 | 358 | ||
350 | static void path_rec_completion(int status, | 359 | static void path_rec_completion(int status, |
@@ -373,16 +382,9 @@ static void path_rec_completion(int status, | |||
373 | struct ib_ah_attr av = { | 382 | struct ib_ah_attr av = { |
374 | .dlid = be16_to_cpu(pathrec->dlid), | 383 | .dlid = be16_to_cpu(pathrec->dlid), |
375 | .sl = pathrec->sl, | 384 | .sl = pathrec->sl, |
376 | .port_num = priv->port | 385 | .port_num = priv->port, |
386 | .static_rate = pathrec->rate | ||
377 | }; | 387 | }; |
378 | int path_rate = ib_sa_rate_enum_to_int(pathrec->rate); | ||
379 | |||
380 | if (path_rate > 0 && priv->local_rate > path_rate) | ||
381 | av.static_rate = (priv->local_rate - 1) / path_rate; | ||
382 | |||
383 | ipoib_dbg(priv, "static_rate %d for local port %dX, path %dX\n", | ||
384 | av.static_rate, priv->local_rate, | ||
385 | ib_sa_rate_enum_to_int(pathrec->rate)); | ||
386 | 388 | ||
387 | ah = ipoib_create_ah(dev, priv->pd, &av); | 389 | ah = ipoib_create_ah(dev, priv->pd, &av); |
388 | } | 390 | } |
@@ -481,7 +483,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | |||
481 | struct ipoib_path *path; | 483 | struct ipoib_path *path; |
482 | struct ipoib_neigh *neigh; | 484 | struct ipoib_neigh *neigh; |
483 | 485 | ||
484 | neigh = kmalloc(sizeof *neigh, GFP_ATOMIC); | 486 | neigh = ipoib_neigh_alloc(skb->dst->neighbour); |
485 | if (!neigh) { | 487 | if (!neigh) { |
486 | ++priv->stats.tx_dropped; | 488 | ++priv->stats.tx_dropped; |
487 | dev_kfree_skb_any(skb); | 489 | dev_kfree_skb_any(skb); |
@@ -489,8 +491,6 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | |||
489 | } | 491 | } |
490 | 492 | ||
491 | skb_queue_head_init(&neigh->queue); | 493 | skb_queue_head_init(&neigh->queue); |
492 | neigh->neighbour = skb->dst->neighbour; | ||
493 | *to_ipoib_neigh(skb->dst->neighbour) = neigh; | ||
494 | 494 | ||
495 | /* | 495 | /* |
496 | * We can only be called from ipoib_start_xmit, so we're | 496 | * We can only be called from ipoib_start_xmit, so we're |
@@ -503,7 +503,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | |||
503 | path = path_rec_create(dev, | 503 | path = path_rec_create(dev, |
504 | (union ib_gid *) (skb->dst->neighbour->ha + 4)); | 504 | (union ib_gid *) (skb->dst->neighbour->ha + 4)); |
505 | if (!path) | 505 | if (!path) |
506 | goto err; | 506 | goto err_path; |
507 | 507 | ||
508 | __path_add(dev, path); | 508 | __path_add(dev, path); |
509 | } | 509 | } |
@@ -521,17 +521,17 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | |||
521 | __skb_queue_tail(&neigh->queue, skb); | 521 | __skb_queue_tail(&neigh->queue, skb); |
522 | 522 | ||
523 | if (!path->query && path_rec_start(dev, path)) | 523 | if (!path->query && path_rec_start(dev, path)) |
524 | goto err; | 524 | goto err_list; |
525 | } | 525 | } |
526 | 526 | ||
527 | spin_unlock(&priv->lock); | 527 | spin_unlock(&priv->lock); |
528 | return; | 528 | return; |
529 | 529 | ||
530 | err: | 530 | err_list: |
531 | *to_ipoib_neigh(skb->dst->neighbour) = NULL; | ||
532 | list_del(&neigh->list); | 531 | list_del(&neigh->list); |
533 | kfree(neigh); | ||
534 | 532 | ||
533 | err_path: | ||
534 | ipoib_neigh_free(neigh); | ||
535 | ++priv->stats.tx_dropped; | 535 | ++priv->stats.tx_dropped; |
536 | dev_kfree_skb_any(skb); | 536 | dev_kfree_skb_any(skb); |
537 | 537 | ||
@@ -763,8 +763,7 @@ static void ipoib_neigh_destructor(struct neighbour *n) | |||
763 | if (neigh->ah) | 763 | if (neigh->ah) |
764 | ah = neigh->ah; | 764 | ah = neigh->ah; |
765 | list_del(&neigh->list); | 765 | list_del(&neigh->list); |
766 | *to_ipoib_neigh(n) = NULL; | 766 | ipoib_neigh_free(neigh); |
767 | kfree(neigh); | ||
768 | } | 767 | } |
769 | 768 | ||
770 | spin_unlock_irqrestore(&priv->lock, flags); | 769 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -773,6 +772,26 @@ static void ipoib_neigh_destructor(struct neighbour *n) | |||
773 | ipoib_put_ah(ah); | 772 | ipoib_put_ah(ah); |
774 | } | 773 | } |
775 | 774 | ||
775 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour) | ||
776 | { | ||
777 | struct ipoib_neigh *neigh; | ||
778 | |||
779 | neigh = kmalloc(sizeof *neigh, GFP_ATOMIC); | ||
780 | if (!neigh) | ||
781 | return NULL; | ||
782 | |||
783 | neigh->neighbour = neighbour; | ||
784 | *to_ipoib_neigh(neighbour) = neigh; | ||
785 | |||
786 | return neigh; | ||
787 | } | ||
788 | |||
789 | void ipoib_neigh_free(struct ipoib_neigh *neigh) | ||
790 | { | ||
791 | *to_ipoib_neigh(neigh->neighbour) = NULL; | ||
792 | kfree(neigh); | ||
793 | } | ||
794 | |||
776 | static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms) | 795 | static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms) |
777 | { | 796 | { |
778 | parms->neigh_destructor = ipoib_neigh_destructor; | 797 | parms->neigh_destructor = ipoib_neigh_destructor; |
@@ -785,20 +804,19 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
785 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 804 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
786 | 805 | ||
787 | /* Allocate RX/TX "rings" to hold queued skbs */ | 806 | /* Allocate RX/TX "rings" to hold queued skbs */ |
788 | 807 | priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, | |
789 | priv->rx_ring = kzalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf), | ||
790 | GFP_KERNEL); | 808 | GFP_KERNEL); |
791 | if (!priv->rx_ring) { | 809 | if (!priv->rx_ring) { |
792 | printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", | 810 | printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n", |
793 | ca->name, IPOIB_RX_RING_SIZE); | 811 | ca->name, ipoib_recvq_size); |
794 | goto out; | 812 | goto out; |
795 | } | 813 | } |
796 | 814 | ||
797 | priv->tx_ring = kzalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf), | 815 | priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring, |
798 | GFP_KERNEL); | 816 | GFP_KERNEL); |
799 | if (!priv->tx_ring) { | 817 | if (!priv->tx_ring) { |
800 | printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", | 818 | printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", |
801 | ca->name, IPOIB_TX_RING_SIZE); | 819 | ca->name, ipoib_sendq_size); |
802 | goto out_rx_ring_cleanup; | 820 | goto out_rx_ring_cleanup; |
803 | } | 821 | } |
804 | 822 | ||
@@ -866,7 +884,7 @@ static void ipoib_setup(struct net_device *dev) | |||
866 | dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN; | 884 | dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN; |
867 | dev->addr_len = INFINIBAND_ALEN; | 885 | dev->addr_len = INFINIBAND_ALEN; |
868 | dev->type = ARPHRD_INFINIBAND; | 886 | dev->type = ARPHRD_INFINIBAND; |
869 | dev->tx_queue_len = IPOIB_TX_RING_SIZE * 2; | 887 | dev->tx_queue_len = ipoib_sendq_size * 2; |
870 | dev->features = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX; | 888 | dev->features = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX; |
871 | 889 | ||
872 | /* MTU will be reset when mcast join happens */ | 890 | /* MTU will be reset when mcast join happens */ |
@@ -1118,6 +1136,14 @@ static int __init ipoib_init_module(void) | |||
1118 | { | 1136 | { |
1119 | int ret; | 1137 | int ret; |
1120 | 1138 | ||
1139 | ipoib_recvq_size = roundup_pow_of_two(ipoib_recvq_size); | ||
1140 | ipoib_recvq_size = min(ipoib_recvq_size, IPOIB_MAX_QUEUE_SIZE); | ||
1141 | ipoib_recvq_size = max(ipoib_recvq_size, IPOIB_MIN_QUEUE_SIZE); | ||
1142 | |||
1143 | ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); | ||
1144 | ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); | ||
1145 | ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE); | ||
1146 | |||
1121 | ret = ipoib_register_debugfs(); | 1147 | ret = ipoib_register_debugfs(); |
1122 | if (ret) | 1148 | if (ret) |
1123 | return ret; | 1149 | return ret; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 93c462eaf4fd..1dae4b238252 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -114,8 +114,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) | |||
114 | */ | 114 | */ |
115 | if (neigh->ah) | 115 | if (neigh->ah) |
116 | ipoib_put_ah(neigh->ah); | 116 | ipoib_put_ah(neigh->ah); |
117 | *to_ipoib_neigh(neigh->neighbour) = NULL; | 117 | ipoib_neigh_free(neigh); |
118 | kfree(neigh); | ||
119 | } | 118 | } |
120 | 119 | ||
121 | spin_unlock_irqrestore(&priv->lock, flags); | 120 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -251,6 +250,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
251 | .port_num = priv->port, | 250 | .port_num = priv->port, |
252 | .sl = mcast->mcmember.sl, | 251 | .sl = mcast->mcmember.sl, |
253 | .ah_flags = IB_AH_GRH, | 252 | .ah_flags = IB_AH_GRH, |
253 | .static_rate = mcast->mcmember.rate, | ||
254 | .grh = { | 254 | .grh = { |
255 | .flow_label = be32_to_cpu(mcast->mcmember.flow_label), | 255 | .flow_label = be32_to_cpu(mcast->mcmember.flow_label), |
256 | .hop_limit = mcast->mcmember.hop_limit, | 256 | .hop_limit = mcast->mcmember.hop_limit, |
@@ -258,17 +258,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
258 | .traffic_class = mcast->mcmember.traffic_class | 258 | .traffic_class = mcast->mcmember.traffic_class |
259 | } | 259 | } |
260 | }; | 260 | }; |
261 | int path_rate = ib_sa_rate_enum_to_int(mcast->mcmember.rate); | ||
262 | |||
263 | av.grh.dgid = mcast->mcmember.mgid; | 261 | av.grh.dgid = mcast->mcmember.mgid; |
264 | 262 | ||
265 | if (path_rate > 0 && priv->local_rate > path_rate) | ||
266 | av.static_rate = (priv->local_rate - 1) / path_rate; | ||
267 | |||
268 | ipoib_dbg_mcast(priv, "static_rate %d for local port %dX, mcmember %dX\n", | ||
269 | av.static_rate, priv->local_rate, | ||
270 | ib_sa_rate_enum_to_int(mcast->mcmember.rate)); | ||
271 | |||
272 | ah = ipoib_create_ah(dev, priv->pd, &av); | 263 | ah = ipoib_create_ah(dev, priv->pd, &av); |
273 | if (!ah) { | 264 | if (!ah) { |
274 | ipoib_warn(priv, "ib_address_create failed\n"); | 265 | ipoib_warn(priv, "ib_address_create failed\n"); |
@@ -618,6 +609,22 @@ int ipoib_mcast_start_thread(struct net_device *dev) | |||
618 | return 0; | 609 | return 0; |
619 | } | 610 | } |
620 | 611 | ||
612 | static void wait_for_mcast_join(struct ipoib_dev_priv *priv, | ||
613 | struct ipoib_mcast *mcast) | ||
614 | { | ||
615 | spin_lock_irq(&priv->lock); | ||
616 | if (mcast && mcast->query) { | ||
617 | ib_sa_cancel_query(mcast->query_id, mcast->query); | ||
618 | mcast->query = NULL; | ||
619 | spin_unlock_irq(&priv->lock); | ||
620 | ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n", | ||
621 | IPOIB_GID_ARG(mcast->mcmember.mgid)); | ||
622 | wait_for_completion(&mcast->done); | ||
623 | } | ||
624 | else | ||
625 | spin_unlock_irq(&priv->lock); | ||
626 | } | ||
627 | |||
621 | int ipoib_mcast_stop_thread(struct net_device *dev, int flush) | 628 | int ipoib_mcast_stop_thread(struct net_device *dev, int flush) |
622 | { | 629 | { |
623 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 630 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
@@ -637,28 +644,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) | |||
637 | if (flush) | 644 | if (flush) |
638 | flush_workqueue(ipoib_workqueue); | 645 | flush_workqueue(ipoib_workqueue); |
639 | 646 | ||
640 | spin_lock_irq(&priv->lock); | 647 | wait_for_mcast_join(priv, priv->broadcast); |
641 | if (priv->broadcast && priv->broadcast->query) { | ||
642 | ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query); | ||
643 | priv->broadcast->query = NULL; | ||
644 | spin_unlock_irq(&priv->lock); | ||
645 | ipoib_dbg_mcast(priv, "waiting for bcast\n"); | ||
646 | wait_for_completion(&priv->broadcast->done); | ||
647 | } else | ||
648 | spin_unlock_irq(&priv->lock); | ||
649 | 648 | ||
650 | list_for_each_entry(mcast, &priv->multicast_list, list) { | 649 | list_for_each_entry(mcast, &priv->multicast_list, list) |
651 | spin_lock_irq(&priv->lock); | 650 | wait_for_mcast_join(priv, mcast); |
652 | if (mcast->query) { | ||
653 | ib_sa_cancel_query(mcast->query_id, mcast->query); | ||
654 | mcast->query = NULL; | ||
655 | spin_unlock_irq(&priv->lock); | ||
656 | ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n", | ||
657 | IPOIB_GID_ARG(mcast->mcmember.mgid)); | ||
658 | wait_for_completion(&mcast->done); | ||
659 | } else | ||
660 | spin_unlock_irq(&priv->lock); | ||
661 | } | ||
662 | 651 | ||
663 | return 0; | 652 | return 0; |
664 | } | 653 | } |
@@ -772,13 +761,11 @@ out: | |||
772 | if (skb->dst && | 761 | if (skb->dst && |
773 | skb->dst->neighbour && | 762 | skb->dst->neighbour && |
774 | !*to_ipoib_neigh(skb->dst->neighbour)) { | 763 | !*to_ipoib_neigh(skb->dst->neighbour)) { |
775 | struct ipoib_neigh *neigh = kmalloc(sizeof *neigh, GFP_ATOMIC); | 764 | struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour); |
776 | 765 | ||
777 | if (neigh) { | 766 | if (neigh) { |
778 | kref_get(&mcast->ah->ref); | 767 | kref_get(&mcast->ah->ref); |
779 | neigh->ah = mcast->ah; | 768 | neigh->ah = mcast->ah; |
780 | neigh->neighbour = skb->dst->neighbour; | ||
781 | *to_ipoib_neigh(skb->dst->neighbour) = neigh; | ||
782 | list_add_tail(&neigh->list, &mcast->neigh_list); | 769 | list_add_tail(&neigh->list, &mcast->neigh_list); |
783 | } | 770 | } |
784 | } | 771 | } |
@@ -913,6 +900,7 @@ void ipoib_mcast_restart_task(void *dev_ptr) | |||
913 | 900 | ||
914 | /* We have to cancel outside of the spinlock */ | 901 | /* We have to cancel outside of the spinlock */ |
915 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { | 902 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { |
903 | wait_for_mcast_join(priv, mcast); | ||
916 | ipoib_mcast_leave(mcast->dev, mcast); | 904 | ipoib_mcast_leave(mcast->dev, mcast); |
917 | ipoib_mcast_free(mcast); | 905 | ipoib_mcast_free(mcast); |
918 | } | 906 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 5f0388027b25..1d49d1643c59 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
@@ -159,8 +159,8 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
159 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 159 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
160 | struct ib_qp_init_attr init_attr = { | 160 | struct ib_qp_init_attr init_attr = { |
161 | .cap = { | 161 | .cap = { |
162 | .max_send_wr = IPOIB_TX_RING_SIZE, | 162 | .max_send_wr = ipoib_sendq_size, |
163 | .max_recv_wr = IPOIB_RX_RING_SIZE, | 163 | .max_recv_wr = ipoib_recvq_size, |
164 | .max_send_sge = 1, | 164 | .max_send_sge = 1, |
165 | .max_recv_sge = 1 | 165 | .max_recv_sge = 1 |
166 | }, | 166 | }, |
@@ -175,7 +175,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
175 | } | 175 | } |
176 | 176 | ||
177 | priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, | 177 | priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, |
178 | IPOIB_TX_RING_SIZE + IPOIB_RX_RING_SIZE + 1); | 178 | ipoib_sendq_size + ipoib_recvq_size + 1); |
179 | if (IS_ERR(priv->cq)) { | 179 | if (IS_ERR(priv->cq)) { |
180 | printk(KERN_WARNING "%s: failed to create CQ\n", ca->name); | 180 | printk(KERN_WARNING "%s: failed to create CQ\n", ca->name); |
181 | goto out_free_pd; | 181 | goto out_free_pd; |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index fd8a95a9c5d3..5bb55742ada6 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -617,6 +617,14 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, | |||
617 | scmnd->sc_data_direction); | 617 | scmnd->sc_data_direction); |
618 | } | 618 | } |
619 | 619 | ||
620 | static void srp_remove_req(struct srp_target_port *target, struct srp_request *req, | ||
621 | int index) | ||
622 | { | ||
623 | list_del(&req->list); | ||
624 | req->next = target->req_head; | ||
625 | target->req_head = index; | ||
626 | } | ||
627 | |||
620 | static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | 628 | static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) |
621 | { | 629 | { |
622 | struct srp_request *req; | 630 | struct srp_request *req; |
@@ -664,9 +672,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
664 | scmnd->host_scribble = (void *) -1L; | 672 | scmnd->host_scribble = (void *) -1L; |
665 | scmnd->scsi_done(scmnd); | 673 | scmnd->scsi_done(scmnd); |
666 | 674 | ||
667 | list_del(&req->list); | 675 | srp_remove_req(target, req, rsp->tag & ~SRP_TAG_TSK_MGMT); |
668 | req->next = target->req_head; | ||
669 | target->req_head = rsp->tag & ~SRP_TAG_TSK_MGMT; | ||
670 | } else | 676 | } else |
671 | req->cmd_done = 1; | 677 | req->cmd_done = 1; |
672 | } | 678 | } |
@@ -1188,12 +1194,10 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) | |||
1188 | spin_lock_irq(target->scsi_host->host_lock); | 1194 | spin_lock_irq(target->scsi_host->host_lock); |
1189 | 1195 | ||
1190 | if (req->cmd_done) { | 1196 | if (req->cmd_done) { |
1191 | list_del(&req->list); | 1197 | srp_remove_req(target, req, req_index); |
1192 | req->next = target->req_head; | ||
1193 | target->req_head = req_index; | ||
1194 | |||
1195 | scmnd->scsi_done(scmnd); | 1198 | scmnd->scsi_done(scmnd); |
1196 | } else if (!req->tsk_status) { | 1199 | } else if (!req->tsk_status) { |
1200 | srp_remove_req(target, req, req_index); | ||
1197 | scmnd->result = DID_ABORT << 16; | 1201 | scmnd->result = DID_ABORT << 16; |
1198 | ret = SUCCESS; | 1202 | ret = SUCCESS; |
1199 | } | 1203 | } |
@@ -1434,6 +1438,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) | |||
1434 | p = match_strdup(args); | 1438 | p = match_strdup(args); |
1435 | if (strlen(p) != 32) { | 1439 | if (strlen(p) != 32) { |
1436 | printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p); | 1440 | printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p); |
1441 | kfree(p); | ||
1437 | goto out; | 1442 | goto out; |
1438 | } | 1443 | } |
1439 | 1444 | ||