[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