[ofa-general] [RFC] ipoib: multicast sender will leave the group when neighbour is cleaned

Yossi Etigin yossi.openib at gmail.com
Mon Jul 28 09:30:15 PDT 2008


Roland,
Can you please comment on this?

Thanks,
Yossi

Yossi Etigin wrote:
>>
>> Would it work to have a more naive approach, and just keep track of the
>> last time each send-only membership was used, and set up a timer that
>> runs, say every minute, and garbage collect send-only memberships that
>> are more than 2 minutes old, or something like that?
>>
> 
> How about this one:
> 
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
> b/drivers/infiniband/ulp/ipoib/ipoib.h
> index ca126fc..7a5998f 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib.h
> +++ b/drivers/infiniband/ulp/ipoib/ipoib.h
> @@ -88,6 +88,7 @@ enum {
>     IPOIB_FLAG_ADMIN_CM      = 9,
>     IPOIB_FLAG_UMCAST      = 10,
>     IPOIB_FLAG_CSUM          = 11,
> +    IPOIB_MCAST_RUN_GC      = 12,
> 
>     IPOIB_MAX_BACKOFF_SECONDS = 16,
> 
> @@ -127,6 +128,7 @@ struct ipoib_mcast {
>     struct list_head  list;
> 
>     unsigned long created;
> +    unsigned long used;
>     unsigned long backoff;
> 
>     unsigned long flags;
> @@ -275,7 +277,8 @@ struct ipoib_dev_priv {
>     struct rb_root multicast_tree;
> 
>     struct delayed_work pkey_poll_task;
> -    struct delayed_work mcast_task;
> +    struct delayed_work mcast_join_task;
> +    struct delayed_work mcast_leave_task;
>     struct work_struct flush_task;
>     struct work_struct restart_task;
>     struct delayed_work ah_reap_task;
> @@ -440,6 +443,7 @@ int ipoib_dev_init(struct net_device *dev, struct 
> ib_device *ca, int port);
> void ipoib_dev_cleanup(struct net_device *dev);
> 
> void ipoib_mcast_join_task(struct work_struct *work);
> +void ipoib_mcast_leave_task(struct work_struct *work);
> void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff 
> *skb);
> 
> void ipoib_mcast_restart_task(struct work_struct *work);
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c 
> b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> index 2442090..b7f4b2b 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> @@ -990,7 +990,8 @@ static void ipoib_setup(struct net_device *dev)
> 
>     INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll);
>     INIT_WORK(&priv->pkey_event_task, ipoib_pkey_event);
> -    INIT_DELAYED_WORK(&priv->mcast_task,   ipoib_mcast_join_task);
> +    INIT_DELAYED_WORK(&priv->mcast_join_task,   ipoib_mcast_join_task);
> +    INIT_DELAYED_WORK(&priv->mcast_leave_task, ipoib_mcast_leave_task);
>     INIT_WORK(&priv->flush_task,   ipoib_ib_dev_flush);
>     INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task);
>     INIT_DELAYED_WORK(&priv->ah_reap_task, ipoib_reap_ah);
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 
> b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> index 3f663fb..1957e93 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> @@ -120,6 +120,7 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct 
> net_device *dev,
> 
>     mcast->dev = dev;
>     mcast->created = jiffies;
> +    mcast->used = jiffies;
>     mcast->backoff = 1;
> 
>     INIT_LIST_HEAD(&mcast->list);
> @@ -389,7 +390,7 @@ static int ipoib_mcast_join_complete(int status,
>         mutex_lock(&mcast_mutex);
>         if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
>             queue_delayed_work(ipoib_workqueue,
> -                       &priv->mcast_task, 0);
> +                       &priv->mcast_join_task, 0);
>         mutex_unlock(&mcast_mutex);
> 
>         if (mcast == priv->broadcast)
> @@ -422,7 +423,7 @@ static int ipoib_mcast_join_complete(int status,
>     mutex_lock(&mcast_mutex);
>     spin_lock_irq(&priv->lock);
>     if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
> -        queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
> +        queue_delayed_work(ipoib_workqueue, &priv->mcast_join_task,
>                    mcast->backoff * HZ);
>     spin_unlock_irq(&priv->lock);
>     mutex_unlock(&mcast_mutex);
> @@ -492,7 +493,7 @@ static void ipoib_mcast_join(struct net_device *dev, 
> struct ipoib_mcast *mcast,
>         mutex_lock(&mcast_mutex);
>         if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
>             queue_delayed_work(ipoib_workqueue,
> -                       &priv->mcast_task,
> +                       &priv->mcast_join_task,
>                        mcast->backoff * HZ);
>         mutex_unlock(&mcast_mutex);
>     }
> @@ -501,7 +502,7 @@ static void ipoib_mcast_join(struct net_device *dev, 
> struct ipoib_mcast *mcast,
> void ipoib_mcast_join_task(struct work_struct *work)
> {
>     struct ipoib_dev_priv *priv =
> -        container_of(work, struct ipoib_dev_priv, mcast_task.work);
> +        container_of(work, struct ipoib_dev_priv, mcast_join_task.work);
>     struct net_device *dev = priv->dev;
> 
>     if (!test_bit(IPOIB_MCAST_RUN, &priv->flags))
> @@ -530,7 +531,7 @@ void ipoib_mcast_join_task(struct work_struct *work)
>             mutex_lock(&mcast_mutex);
>             if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
>                 queue_delayed_work(ipoib_workqueue,
> -                           &priv->mcast_task, HZ);
> +                           &priv->mcast_join_task, HZ);
>             mutex_unlock(&mcast_mutex);
>             return;
>         }
> @@ -591,7 +592,9 @@ int ipoib_mcast_start_thread(struct net_device *dev)
> 
>     mutex_lock(&mcast_mutex);
>     if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags))
> -        queue_delayed_work(ipoib_workqueue, &priv->mcast_task, 0);
> +        queue_delayed_work(ipoib_workqueue, &priv->mcast_join_task, 0);
> +    if (!test_and_set_bit(IPOIB_MCAST_RUN_GC, &priv->flags))
> +        queue_delayed_work(ipoib_workqueue, &priv->mcast_leave_task, 0);
>     mutex_unlock(&mcast_mutex);
> 
>     spin_lock_irq(&priv->lock);
> @@ -613,7 +616,9 @@ int ipoib_mcast_stop_thread(struct net_device *dev, 
> int flush)
> 
>     mutex_lock(&mcast_mutex);
>     clear_bit(IPOIB_MCAST_RUN, &priv->flags);
> -    cancel_delayed_work(&priv->mcast_task);
> +    clear_bit(IPOIB_MCAST_RUN_GC, &priv->flags);
> +    cancel_delayed_work(&priv->mcast_join_task);
> +    cancel_delayed_work(&priv->mcast_leave_task);
>     mutex_unlock(&mcast_mutex);
> 
>     if (flush)
> @@ -720,6 +725,7 @@ out:
>             }
>         }
> 
> +        mcast->used = jiffies;
>         ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
>     }
> 
> @@ -864,6 +870,33 @@ void ipoib_mcast_restart_task(struct work_struct 
> *work)
>         ipoib_mcast_start_thread(dev);
> }
> 
> +void ipoib_mcast_leave_task(struct work_struct *work)
> +{
> +    struct ipoib_dev_priv *priv =
> +        container_of(work, struct ipoib_dev_priv, mcast_leave_task.work);
> +    struct net_device *dev = priv->dev;
> +    struct ipoib_mcast *mcast, *tmcast;
> +    LIST_HEAD(remove_list);
> +   
> +    if (!test_bit(IPOIB_MCAST_RUN_GC, &priv->flags))
> +        return;
> +   
> +    list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) {
> +        if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags) &&
> +            time_before(mcast->used, jiffies - 120 * HZ)) {
> +            rb_erase(&mcast->rb_node, &priv->multicast_tree);
> +            list_move_tail(&mcast->list, &remove_list);
> +        }
> +    }
> +
> +    list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
> +        ipoib_mcast_leave(dev, mcast);
> +        ipoib_mcast_free(mcast);
> +    }
> +   
> +    queue_delayed_work(ipoib_workqueue, &priv->mcast_leave_task, 60 * HZ);
> +}
> +
> #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
> 
> struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
> _______________________________________________
> general mailing list
> general at lists.openfabrics.org
> http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general
> 
> To unsubscribe, please visit 
> http://openib.org/mailman/listinfo/openib-general
> 



More information about the general mailing list