The following kills sdp_link.h and converts sdp_link.c to use linux/list.h
Locking is still missing here.

Signed-off-by: Michael S. Tsirkin <[EMAIL PROTECTED]>

Index: linux-2.6.12.2/drivers/infiniband/ulp/sdp/sdp_link.c
===================================================================
--- linux-2.6.12.2.orig/drivers/infiniband/ulp/sdp/sdp_link.c
+++ linux-2.6.12.2/drivers/infiniband/ulp/sdp/sdp_link.c
@@ -35,17 +35,105 @@
 
 #include "ipoib.h"
 #include "sdp_main.h"
-#include "sdp_link.h"
 
-static kmem_cache_t *wait_cache = NULL;
-static kmem_cache_t *info_cache = NULL;
+#define SDP_LINK_F_VALID 0x01 /* valid path info record. */
+#define SDP_LINK_F_ARP   0x02 /* arp request in progress. */
+#define SDP_LINK_F_PATH  0x04 /* arp request in progress. */
+/*
+ * wait for an ARP event to complete.
+ */
+struct sdp_path_info {
+       u32 src;                    /* source IP address. */
+       u32 dst;                    /* destination IP address */
+       int dif;                    /* bound device interface option */
+       u32 gw;                     /* gateway IP address */
+       int qid;                    /* path record query ID */
+       u8  port;                   /* HCA port */
+       u32 flags;                  /* record flags */
+       int sa_time;                /* path_rec request timeout */
+       unsigned long arp_time;     /* ARP request timeout */
+       unsigned long use;          /* last time accessed. */
+       struct ib_device  *ca;      /* HCA device. */
+       struct ib_sa_path_rec path; /* path record info */
+        struct ib_sa_query *query;
 
-static struct sdp_path_info *info_list = NULL;
+       struct work_struct timer;   /* arp request timers. */
+
+       struct list_head info_list;
+
+       struct list_head wait_list;
+};
+
+struct sdp_path_wait {
+       u64 id;  /* request identifier */
+       void (*completion)(u64 id,
+                          int status,
+                          u32 dst_addr,
+                          u32 src_addr,
+                          u8  hw_port,
+                          struct ib_device *ca,
+                          struct ib_sa_path_rec *path,
+                          void *arg);
+       void *arg;
+       int retry;
+       struct list_head list;
+};
+
+struct sdp_work {
+       struct work_struct work;
+       void *arg;
+};
+
+struct sdp_link_arp {
+       /*
+        * generic arp header
+        */
+       u16 addr_type;    /* format of hardware address   */
+       u16 proto_type;   /* format of protocol address   */
+       u8  addr_len;     /* length of hardware address   */
+       u8  proto_len;    /* length of protocol address   */
+       u16 op;           /* ARP opcode (command)         */
+       /*
+        * begin IB specific section
+        */
+       u32          src_qpn; /* MSB = reserved, low 3 bytes=QPN */
+       union ib_gid src_gid;
+       u32          src_ip;
+
+       u32          dst_qpn; /* MSB = reserved, low 3 bytes=QPN */
+       union ib_gid dst_gid;
+       u32          dst_ip;
+
+} __attribute__ ((packed)); /* sdp_link_arp */
+
+#define SDP_LINK_SWEEP_INTERVAL (10 * (HZ)) /* frequency of sweep function */
+#define SDP_LINK_INFO_TIMEOUT   (300UL * (HZ)) /* unused time */
+#define SDP_LINK_SA_RETRY       (3)          /* number of SA retry requests */
+#define SDP_LINK_ARP_RETRY      (3)          /* number of ARP retry requests */
+
+#define SDP_LINK_SA_TIME_MIN    (500)   /* milliseconds. */
+#define SDP_LINK_SA_TIME_MAX    (10000) /* milliseconds. */
+#define SDP_LINK_ARP_TIME_MIN   (HZ)
+#define SDP_LINK_ARP_TIME_MAX   (32UL * (HZ))
+
+#if 0
+#define SDP_IPOIB_RETRY_VALUE    3        /* number of retries. */
+#define SDP_IPOIB_RETRY_INTERVAL (HZ * 1) /* retry frequency */
+
+#define SDP_DEV_PATH_WAIT       (5 * (HZ))
+#define SDP_PATH_TIMER_INTERVAL (15 * (HZ))  /* cache sweep frequency */
+#define SDP_PATH_REAPING_AGE    (300 * (HZ)) /* idle time before reaping */
+#endif
+
+static kmem_cache_t *wait_cache;
+static kmem_cache_t *info_cache;
+
+static LIST_HEAD(info_list);
 
 static struct workqueue_struct *link_wq;
 static struct work_struct       link_timer;
 
-static u64 path_lookup_id = 0;
+static u64 path_lookup_id;
 
 #define _SDP_PATH_LOOKUP_ID() \
       ((++path_lookup_id) ? path_lookup_id : ++path_lookup_id)
@@ -95,42 +183,6 @@ static void sdp_link_path_complete(u64 i
 }
 
 /*
- * sdp_path_wait_add - add a wait entry into the wait list for a path
- */
-static void sdp_path_wait_add(struct sdp_path_info *info,
-                             struct sdp_path_wait *wait)
-{
-
-       wait->next      = info->wait_list;
-       info->wait_list = wait;
-       wait->pext      = &info->wait_list;
-
-       if (wait->next)
-               wait->next->pext = &wait->next;
-}
-
-/*
- * sdp_path_wait_destroy - destroy an entry for a wait element
- */
-static void sdp_path_wait_destroy(struct sdp_path_wait *wait)
-{
-       /*
-        * if it's in the list, pext will not be null
-        */
-       if (wait->pext) {
-               if (wait->next)
-                       wait->next->pext = wait->pext;
-
-               *(wait->pext) = wait->next;
-
-               wait->pext = NULL;
-               wait->next = NULL;
-       }
-
-       kmem_cache_free(wait_cache, wait);
-}
-
-/*
  * sdp_path_wait_complete - complete an entry for a wait element
  */
 static void sdp_path_wait_complete(struct sdp_path_wait *wait,
@@ -142,21 +194,8 @@ static void sdp_path_wait_complete(struc
                                wait->completion,
                                wait->arg);
 
-       sdp_path_wait_destroy(wait);
-}
-
-/*
- * sdp_path_info_lookup - lookup a path record entry
- */
-static struct sdp_path_info *sdp_path_info_lookup(u32 dst_ip, int dev_if)
-{
-       struct sdp_path_info *info;
-
-       for (info = info_list; info; info = info->next)
-               if (dst_ip == info->dst && dev_if == info->dif)
-                       break;
-
-       return info;
+       list_del(&wait->list);
+       kmem_cache_free(wait_cache, wait);
 }
 
 /*
@@ -172,19 +211,15 @@ static struct sdp_path_info *sdp_path_in
 
        memset(info, 0, sizeof(struct sdp_path_info));
 
-       info->next = info_list;
-       info_list = info;
-       info->pext = &info_list;
-
-       if (info->next)
-               info->next->pext = &info->next;
-
        info->dst = dst_ip;
        info->dif = dev_if;
        info->use = jiffies;
 
        info->sa_time  = SDP_LINK_SA_TIME_MIN;
        info->arp_time = SDP_LINK_ARP_TIME_MIN;
+
+       INIT_LIST_HEAD(&info->wait_list);
+       list_add(&info->info_list, &info_list);
        INIT_WORK(&info->timer, do_link_path_lookup, info);
 
        return info;
@@ -195,21 +230,11 @@ static struct sdp_path_info *sdp_path_in
  */
 static void sdp_path_info_destroy(struct sdp_path_info *info, int status)
 {
-       struct sdp_path_wait *wait;
-       /*
-        * if it's in the list, pext will not be null
-        */
-       if (info->pext) {
-               if (info->next)
-                       info->next->pext = info->pext;
-
-               *(info->pext) = info->next;
+       struct sdp_path_wait *wait, *tmp;
+       /* TODO: replace by list_del once we have proper locking */
+       list_del_init(&info->info_list);
 
-               info->pext = NULL;
-               info->next = NULL;
-       }
-
-       while ((wait = info->wait_list))
+       list_for_each_entry_safe(wait, tmp, &info->wait_list, list)
                sdp_path_wait_complete(wait, info, status);
 
        cancel_delayed_work(&info->timer);
@@ -222,7 +247,7 @@ static void sdp_path_info_destroy(struct
 static void sdp_link_path_rec_done(int status, struct ib_sa_path_rec *resp,
                                   void *context)
 {
-       struct sdp_path_info *info = (struct sdp_path_info *)context;
+       struct sdp_path_info *info = context;
        struct sdp_path_wait *wait;
        struct sdp_path_wait *sweep;
        int result;
@@ -241,23 +266,20 @@ static void sdp_link_path_rec_done(int s
                info->path   = *resp;
        }
 
-       sweep = info->wait_list;
-       while (sweep) {
-               wait  = sweep;
-               sweep = sweep->next;
+       list_for_each_entry_safe(wait, sweep, &info->wait_list, list) {
                /*
                 * on timeout increment retries.
                 */
                if (status == -ETIMEDOUT)
                        wait->retry++;
 
-               if (!status || SDP_LINK_SA_RETRY < wait->retry)
+               if (!status || wait->retry > SDP_LINK_SA_RETRY)
                        sdp_path_wait_complete(wait, info, status);
        }
        /*
         * retry if anyone is waiting.
         */
-       if (info->wait_list) {
+       if (!list_empty(&info->wait_list)) {
                info->sa_time = min(info->sa_time * 2, SDP_LINK_SA_TIME_MAX);
 
                result = ib_sa_path_rec_get(info->ca,
@@ -348,10 +370,11 @@ static void do_link_path_lookup(void *da
                        }
                }
        };
+
        /*
         * path request in progress?
         */
-       if (info->query)
+       if (info->flags & SDP_LINK_F_PATH)
                goto done;
        /*
         * route information present, but no path query.
@@ -483,16 +506,11 @@ static void do_link_path_lookup(void *da
                struct sdp_path_wait *sweep;
                struct sdp_path_wait *wait;
 
-               sweep = info->wait_list;
-               while (sweep) {
-                       wait = sweep;
-                       sweep = sweep->next;
-
-                       if (SDP_LINK_SA_RETRY < wait->retry++)
+               list_for_each_entry_safe(wait, sweep, &info->wait_list, list)
+                       if (wait->retry++ > SDP_LINK_ARP_RETRY)
                                sdp_path_wait_complete(wait, info, -ETIMEDOUT);
-               }
 
-               if (!info->wait_list) {
+               if (list_empty(&info->wait_list)) {
                        result = -ETIMEDOUT;
                        goto error;
                }
@@ -551,11 +569,12 @@ int sdp_link_path_lookup(u32 dst_addr,  
        int result;
 
        *id = _SDP_PATH_LOOKUP_ID();
-       /*
-        * lookup entry, create if not found and add to wait list.
-        */
-       info = sdp_path_info_lookup(dst_addr, bound_dev_if);
-       if (!info) {
+
+       list_for_each_entry(info, &info_list, info_list)
+               if (info->dst == dst_addr && info->dif == bound_dev_if)
+                       break;
+
+       if (&info->info_list == &info_list) {
                info = sdp_path_info_create(dst_addr, bound_dev_if);
                if (!info) {
                        sdp_dbg_warn(NULL, "Failed to create path object");
@@ -586,7 +605,8 @@ int sdp_link_path_lookup(u32 dst_addr,  
        wait->completion = completion;
        wait->arg        = arg;
 
-       sdp_path_wait_add(info, wait);
+       list_add(&wait->list, &info->wait_list);
+
        /*
         * initiate address lookup, if not in progress.
         */
@@ -610,11 +630,7 @@ static void sdp_link_sweep(void *data)
        struct sdp_path_info *info;
        struct sdp_path_info *sweep;
 
-       sweep = info_list;
-       while (sweep) {
-               info  = sweep;
-               sweep = sweep->next;
-
+       list_for_each_entry_safe(info, sweep, &info_list, info_list) {
                if (jiffies > (info->use + SDP_LINK_INFO_TIMEOUT)) {
                        sdp_dbg_ctrl(NULL,
                                     "info delete <%d.%d.%d.%d> <%lu:%lu>",
@@ -657,11 +673,11 @@ static void sdp_link_arp_work(void *data
        /*
         * find a path info structure for the source IP address.
         */
-       for (info = info_list; info; info = info->next)
+       list_for_each_entry(info, &info_list, info_list)
                if (info->dst == arp->src_ip)
                        break;
 
-       if (!info)
+       if (&info->info_list == &info_list)
                goto done;
        /*
         * update record info, and request new path record data.
@@ -788,14 +804,10 @@ error_path:
 void sdp_link_addr_cleanup(void)
 {
        struct sdp_path_info *info;
+       struct sdp_path_info *sweep;
 
        sdp_dbg_init("Link level services cleanup.");
        /*
-        * clear objects
-        */
-       while ((info = info_list))
-               sdp_path_info_destroy(info, -EINTR);
-       /*
         * remove ARP packet processing.
         */
        dev_remove_pack(&sdp_arp_type);
@@ -806,6 +818,11 @@ void sdp_link_addr_cleanup(void)
        flush_workqueue(link_wq);
        destroy_workqueue(link_wq);
        /*
+        * clear objects
+        */
+       list_for_each_entry_safe(info, sweep, &info_list, info_list)
+               sdp_path_info_destroy(info, -EINTR);
+       /*
         * destroy caches
         */
        kmem_cache_destroy(info_cache);

-- 
MST
_______________________________________________
openib-general mailing list
openib-general@openib.org
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to