[openib-general] [PATCH] sdp: use linux/list.h in sdp_link.c

Michael S. Tsirkin mst at mellanox.co.il
Mon Aug 29 08:00:42 PDT 2005


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 <mst at mellanox.co.il>

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



More information about the general mailing list