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