diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib.h')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 86df632ea612..ca43901ed861 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -92,6 +92,8 @@ enum { | |||
92 | IPOIB_STOP_REAPER = 7, | 92 | IPOIB_STOP_REAPER = 7, |
93 | IPOIB_FLAG_ADMIN_CM = 9, | 93 | IPOIB_FLAG_ADMIN_CM = 9, |
94 | IPOIB_FLAG_UMCAST = 10, | 94 | IPOIB_FLAG_UMCAST = 10, |
95 | IPOIB_STOP_NEIGH_GC = 11, | ||
96 | IPOIB_NEIGH_TBL_FLUSH = 12, | ||
95 | 97 | ||
96 | IPOIB_MAX_BACKOFF_SECONDS = 16, | 98 | IPOIB_MAX_BACKOFF_SECONDS = 16, |
97 | 99 | ||
@@ -260,6 +262,20 @@ struct ipoib_ethtool_st { | |||
260 | u16 max_coalesced_frames; | 262 | u16 max_coalesced_frames; |
261 | }; | 263 | }; |
262 | 264 | ||
265 | struct ipoib_neigh_hash { | ||
266 | struct ipoib_neigh __rcu **buckets; | ||
267 | struct rcu_head rcu; | ||
268 | u32 mask; | ||
269 | u32 size; | ||
270 | }; | ||
271 | |||
272 | struct ipoib_neigh_table { | ||
273 | struct ipoib_neigh_hash __rcu *htbl; | ||
274 | rwlock_t rwlock; | ||
275 | atomic_t entries; | ||
276 | struct completion flushed; | ||
277 | }; | ||
278 | |||
263 | /* | 279 | /* |
264 | * Device private locking: network stack tx_lock protects members used | 280 | * Device private locking: network stack tx_lock protects members used |
265 | * in TX fast path, lock protects everything else. lock nests inside | 281 | * in TX fast path, lock protects everything else. lock nests inside |
@@ -279,6 +295,8 @@ struct ipoib_dev_priv { | |||
279 | struct rb_root path_tree; | 295 | struct rb_root path_tree; |
280 | struct list_head path_list; | 296 | struct list_head path_list; |
281 | 297 | ||
298 | struct ipoib_neigh_table ntbl; | ||
299 | |||
282 | struct ipoib_mcast *broadcast; | 300 | struct ipoib_mcast *broadcast; |
283 | struct list_head multicast_list; | 301 | struct list_head multicast_list; |
284 | struct rb_root multicast_tree; | 302 | struct rb_root multicast_tree; |
@@ -291,7 +309,7 @@ struct ipoib_dev_priv { | |||
291 | struct work_struct flush_heavy; | 309 | struct work_struct flush_heavy; |
292 | struct work_struct restart_task; | 310 | struct work_struct restart_task; |
293 | struct delayed_work ah_reap_task; | 311 | struct delayed_work ah_reap_task; |
294 | 312 | struct delayed_work neigh_reap_task; | |
295 | struct ib_device *ca; | 313 | struct ib_device *ca; |
296 | u8 port; | 314 | u8 port; |
297 | u16 pkey; | 315 | u16 pkey; |
@@ -377,13 +395,16 @@ struct ipoib_neigh { | |||
377 | #ifdef CONFIG_INFINIBAND_IPOIB_CM | 395 | #ifdef CONFIG_INFINIBAND_IPOIB_CM |
378 | struct ipoib_cm_tx *cm; | 396 | struct ipoib_cm_tx *cm; |
379 | #endif | 397 | #endif |
380 | union ib_gid dgid; | 398 | u8 daddr[INFINIBAND_ALEN]; |
381 | struct sk_buff_head queue; | 399 | struct sk_buff_head queue; |
382 | 400 | ||
383 | struct neighbour *neighbour; | ||
384 | struct net_device *dev; | 401 | struct net_device *dev; |
385 | 402 | ||
386 | struct list_head list; | 403 | struct list_head list; |
404 | struct ipoib_neigh __rcu *hnext; | ||
405 | struct rcu_head rcu; | ||
406 | atomic_t refcnt; | ||
407 | unsigned long alive; | ||
387 | }; | 408 | }; |
388 | 409 | ||
389 | #define IPOIB_UD_MTU(ib_mtu) (ib_mtu - IPOIB_ENCAP_LEN) | 410 | #define IPOIB_UD_MTU(ib_mtu) (ib_mtu - IPOIB_ENCAP_LEN) |
@@ -394,21 +415,17 @@ static inline int ipoib_ud_need_sg(unsigned int ib_mtu) | |||
394 | return IPOIB_UD_BUF_SIZE(ib_mtu) > PAGE_SIZE; | 415 | return IPOIB_UD_BUF_SIZE(ib_mtu) > PAGE_SIZE; |
395 | } | 416 | } |
396 | 417 | ||
397 | /* | 418 | void ipoib_neigh_dtor(struct ipoib_neigh *neigh); |
398 | * We stash a pointer to our private neighbour information after our | 419 | static inline void ipoib_neigh_put(struct ipoib_neigh *neigh) |
399 | * hardware address in neigh->ha. The ALIGN() expression here makes | ||
400 | * sure that this pointer is stored aligned so that an unaligned | ||
401 | * load is not needed to dereference it. | ||
402 | */ | ||
403 | static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh) | ||
404 | { | 420 | { |
405 | return (void*) neigh + ALIGN(offsetof(struct neighbour, ha) + | 421 | if (atomic_dec_and_test(&neigh->refcnt)) |
406 | INFINIBAND_ALEN, sizeof(void *)); | 422 | ipoib_neigh_dtor(neigh); |
407 | } | 423 | } |
408 | 424 | struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr); | |
409 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh, | 425 | struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, |
410 | struct net_device *dev); | 426 | struct net_device *dev); |
411 | void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh); | 427 | void ipoib_neigh_free(struct ipoib_neigh *neigh); |
428 | void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid); | ||
412 | 429 | ||
413 | extern struct workqueue_struct *ipoib_workqueue; | 430 | extern struct workqueue_struct *ipoib_workqueue; |
414 | 431 | ||
@@ -425,7 +442,6 @@ static inline void ipoib_put_ah(struct ipoib_ah *ah) | |||
425 | { | 442 | { |
426 | kref_put(&ah->ref, ipoib_free_ah); | 443 | kref_put(&ah->ref, ipoib_free_ah); |
427 | } | 444 | } |
428 | |||
429 | int ipoib_open(struct net_device *dev); | 445 | int ipoib_open(struct net_device *dev); |
430 | int ipoib_add_pkey_attr(struct net_device *dev); | 446 | int ipoib_add_pkey_attr(struct net_device *dev); |
431 | int ipoib_add_umcast_attr(struct net_device *dev); | 447 | int ipoib_add_umcast_attr(struct net_device *dev); |
@@ -455,7 +471,7 @@ void ipoib_dev_cleanup(struct net_device *dev); | |||
455 | 471 | ||
456 | void ipoib_mcast_join_task(struct work_struct *work); | 472 | void ipoib_mcast_join_task(struct work_struct *work); |
457 | void ipoib_mcast_carrier_on_task(struct work_struct *work); | 473 | void ipoib_mcast_carrier_on_task(struct work_struct *work); |
458 | void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb); | 474 | void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb); |
459 | 475 | ||
460 | void ipoib_mcast_restart_task(struct work_struct *work); | 476 | void ipoib_mcast_restart_task(struct work_struct *work); |
461 | int ipoib_mcast_start_thread(struct net_device *dev); | 477 | int ipoib_mcast_start_thread(struct net_device *dev); |
@@ -517,10 +533,10 @@ static inline int ipoib_cm_admin_enabled(struct net_device *dev) | |||
517 | test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); | 533 | test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); |
518 | } | 534 | } |
519 | 535 | ||
520 | static inline int ipoib_cm_enabled(struct net_device *dev, struct neighbour *n) | 536 | static inline int ipoib_cm_enabled(struct net_device *dev, u8 *hwaddr) |
521 | { | 537 | { |
522 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 538 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
523 | return IPOIB_CM_SUPPORTED(n->ha) && | 539 | return IPOIB_CM_SUPPORTED(hwaddr) && |
524 | test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); | 540 | test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); |
525 | } | 541 | } |
526 | 542 | ||
@@ -575,7 +591,7 @@ static inline int ipoib_cm_admin_enabled(struct net_device *dev) | |||
575 | { | 591 | { |
576 | return 0; | 592 | return 0; |
577 | } | 593 | } |
578 | static inline int ipoib_cm_enabled(struct net_device *dev, struct neighbour *n) | 594 | static inline int ipoib_cm_enabled(struct net_device *dev, u8 *hwaddr) |
579 | 595 | ||
580 | { | 596 | { |
581 | return 0; | 597 | return 0; |