[openib-general] [PATCH] move IP2PR/SDP to the native IPoIB driver
Libor Michalek
Wed Oct 13 13:44:20 PDT 2004
On Wed, Oct 06, 2004 at 01:32:56PM -0700, Roland Dreier wrote:
> I've just committed this patch. It removes the fake ethernet layer
> and starts turning IPoIB into a native driver (with addr_len 20 and
> type ARPHRD_INFINIBAND). The driver is working pretty well with these
> changes, although multicast is not working at all and there are lots
> of leaks and races that I still need to fix up.
>
> ip2pr (and indirectly sdp) are broken by these changes, but Libor has
> said he will work on fixing this up.
This patch gets ip2pr working on top of the new native ipoib driver
that you checked in. The main change was removing the step of looking
up the hardware address, from the arp cache or arp packet header, in
the ipoib hardware-to-gid table. Instead we now use the gid directly
in the arp cache or arp packet header.
-Libor
Index: infiniband/ulp/Kconfig
===================================================================
--- infiniband/ulp/Kconfig (revision 974)
+++ infiniband/ulp/Kconfig (working copy)
@@ -32,7 +32,7 @@
config INFINIBAND_SDP
tristate "Sockets Direct Protocol"
- depends on BROKEN && INFINIBAND && INFINIBAND_IPOIB
+ depends on INFINIBAND && INFINIBAND_IPOIB
select INFINIBAND_CM
---help---
Support for Sockets Direct Protocol (SDP). This provides
Index: infiniband/ulp/ipoib/Makefile
===================================================================
--- infiniband/ulp/ipoib/Makefile (revision 985)
+++ infiniband/ulp/ipoib/Makefile (working copy)
@@ -3,10 +3,8 @@
-D_NO_DATA_PATH_TRACE
obj-$(CONFIG_INFINIBAND_IPOIB) += ib_ipoib.o
+obj-$(CONFIG_INFINIBAND_IPOIB) += ib_ip2pr.o
-# ip2pr is BROKEN now
-# obj-$(CONFIG_INFINIBAND_IPOIB) += ib_ip2pr.o
-
ib_ipoib-objs := \
ipoib_main.o \
ipoib_ib.o \
Index: infiniband/ulp/ipoib/ip2pr_priv.h
===================================================================
--- infiniband/ulp/ipoib/ip2pr_priv.h (revision 985)
+++ infiniband/ulp/ipoib/ip2pr_priv.h (working copy)
@@ -122,10 +122,10 @@
/*
* begin ethernet
*/
- u8 src_hw[ETH_ALEN];
- u32 src_ip;
- u8 dst_hw[ETH_ALEN];
- u32 dst_ip;
+ struct ip2pr_ipoib_addr src_hw;
+ u32 src_ip;
+ struct ip2pr_ipoib_addr dst_hw;
+ u32 dst_ip;
} __attribute__ ((packed));
typedef enum {
@@ -193,30 +193,32 @@
* wait for an ARP event to complete.
*/
struct ip2pr_ipoib_wait {
- s8 type; /* ip2pr or gid2pr */
- tIP2PR_PATH_LOOKUP_ID plid; /* request identifier */
- void *func; /* callback function for completion */
- void *arg; /* user argument */
- struct net_device *dev; /* ipoib device */
- tTS_KERNEL_TIMER_STRUCT timer; /* retry timer */
- u8 retry; /* retry counter */
- u8 flags; /* usage flags */
- u8 state; /* current state */
- u8 hw[ETH_ALEN]; /* hardware address */
- u32 src_addr; /* requested address. */
- u32 dst_addr; /* requested address. */
- u32 gw_addr; /* next hop IP address */
- u8 local_rt; /* local route only */
- s32 bound_dev; /* bound device interface */
- tTS_IB_GID src_gid; /* source GID */
- tTS_IB_GID dst_gid; /* destination GID */
- u16 pkey; /* pkey to use */
- tTS_IB_PORT hw_port; /* hardware port */
- struct ib_device *ca; /* hardware HCA */
- u32 prev_timeout; /* timeout value for pending request */
- tTS_IB_CLIENT_QUERY_TID tid; /* path record lookup transactionID */
+ s8 type; /* ip2pr or gid2pr */
+ tIP2PR_PATH_LOOKUP_ID plid; /* request identifier */
+ void *func; /* callback function for completion */
+ void *arg; /* user argument */
+ u8 state; /* current state */
+ u8 flags; /* usage flags */
+ tTS_KERNEL_TIMER_STRUCT timer; /* retry timer */
+ u8 retry; /* retry counter */
+ u32 prev_timeout; /* timeout value for pending request */
+ tTS_IB_CLIENT_QUERY_TID tid; /* path record lookup transactionID */
+
+ u8 local_rt; /* local route only */
+ s32 bound_dev; /* bound device interface */
+ u32 src_addr; /* requested address. */
+ u32 dst_addr; /* requested address. */
+ u32 gw_addr; /* next hop IP address */
+
+ struct net_device *dev; /* ipoib device */
+ struct ip2pr_ipoib_addr src_hw; /* source QP/GID */
+ struct ip2pr_ipoib_addr dst_hw; /* destination QP/GID */
+ u16 pkey; /* pkey to use */
+ tTS_IB_PORT hw_port; /* hardware port */
+ struct ib_device *ca; /* hardware HCA */
+
spinlock_t lock;
- struct ip2pr_ipoib_wait *next; /* next element in wait list. */
+ struct ip2pr_ipoib_wait *next; /* next element in wait list. */
struct ip2pr_ipoib_wait **p_next; /* previous next element in list */
struct work_struct arp_completion;
};
Index: infiniband/ulp/ipoib/ip2pr_link.c
===================================================================
--- infiniband/ulp/ipoib/ip2pr_link.c (revision 985)
+++ infiniband/ulp/ipoib/ip2pr_link.c (working copy)
@@ -687,9 +687,10 @@
/* ip2pr_path_record_complete -- path lookup complete, save result */
static s32 ip2pr_path_record_complete(tTS_IB_CLIENT_QUERY_TID tid, s32 status,
struct ib_path_record *path,
- s32 remaining, void *arg)
+ s32 remaining,
+ void *arg)
{
- struct ip2pr_ipoib_wait *ipoib_wait = (struct ip2pr_ipoib_wait *) arg;
+ struct ip2pr_ipoib_wait *ipoib_wait = (struct ip2pr_ipoib_wait *)arg;
struct ip2pr_path_element *path_elmt = NULL;
s32 result;
@@ -703,7 +704,6 @@
tid, ipoib_wait->tid);
return -EFAULT;
}
- /* if */
/*
* path lookup is complete
*/
@@ -714,58 +714,69 @@
remaining);
}
- /* if */
+ TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_INOUT,
+ "POST: Status <%d> path completion:", status);
+ TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_INOUT,
+ "POST: <%p:%d:%04x> <%016llx:%016llx> <%016llx:%016llx>",
+ ipoib_wait->ca,
+ ipoib_wait->hw_port,
+ ipoib_wait->pkey,
+ be64_to_cpu(ipoib_wait->src_hw.gid.s.high),
+ be64_to_cpu(ipoib_wait->src_hw.gid.s.low),
+ be64_to_cpu(ipoib_wait->dst_hw.gid.s.high),
+ be64_to_cpu(ipoib_wait->dst_hw.gid.s.low));
/*
* Save result.
*/
switch (status) {
case -ETIMEDOUT:
- if (0 < ipoib_wait->retry--) {
- ip2pr_path_timeout++;
- ipoib_wait->prev_timeout = (ipoib_wait->prev_timeout * 2); /* backoff */
- if (ipoib_wait->prev_timeout > _tsIp2prLinkRoot.backoff)
- ipoib_wait->prev_timeout =
- _tsIp2prLinkRoot.backoff;
+ if (0 == ipoib_wait->retry--) {
/*
- * reinitiate path record resolution
- */
- result = tsIbPathRecordRequest(ipoib_wait->ca,
- ipoib_wait->hw_port,
- ipoib_wait->src_gid,
- ipoib_wait->dst_gid,
- ipoib_wait->pkey,
- TS_IB_PATH_RECORD_FORCE_REMOTE,
- (ipoib_wait->
- prev_timeout * HZ) +
- (jiffies & 0x0f), 0,
- ip2pr_path_record_complete,
- ipoib_wait,
- &ipoib_wait->tid);
- if (0 != result) {
-
- TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
- "FUNC: Error initiating path record request. <%d>",
- result);
- status = result;
- goto callback;
- } /* if */
- } /* if */
- else {
- /*
* no more retries, failure.
*/
goto callback;
- } /* else */
+ }
+
+ ip2pr_path_timeout++;
+ ipoib_wait->prev_timeout = (ipoib_wait->prev_timeout * 2);
+ if (ipoib_wait->prev_timeout > _tsIp2prLinkRoot.backoff) {
+
+ ipoib_wait->prev_timeout = _tsIp2prLinkRoot.backoff;
+ }
+ /*
+ * reinitiate path record resolution
+ */
+ result = tsIbPathRecordRequest(ipoib_wait->ca,
+ ipoib_wait->hw_port,
+ ipoib_wait->src_hw.gid.all,
+ ipoib_wait->dst_hw.gid.all,
+ ipoib_wait->pkey,
+ TS_IB_PATH_RECORD_FORCE_REMOTE,
+ (ipoib_wait->prev_timeout * HZ) +
+ (jiffies & 0x0f),
+ 0,
+ ip2pr_path_record_complete,
+ ipoib_wait,
+ &ipoib_wait->tid);
+ if (0 != result) {
+
+ TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
+ "FUNC: Path record request error. <%d>",
+ result);
+
+ status = result;
+ goto callback;
+ } /* if */
+
break;
case 0:
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_INOUT,
- "POST: Path record lookup complete. <%016llx:%016llx:%d>",
- be64_to_cpu(*(u64 *) path->dgid),
- be64_to_cpu(*(u64 *)
- (path->dgid + sizeof(u64))),
+ "POST: Path record complete. <%016llx:%016llx:%d>",
+ be64_to_cpu(*(u64 *)path->dgid),
+ be64_to_cpu(*(u64 *)(path->dgid + sizeof(u64))),
path->dlid);
result = ip2pr_path_element_create(ipoib_wait->dst_addr,
@@ -774,25 +785,27 @@
ipoib_wait->ca,
path, &path_elmt);
if (0 > result) {
-
+
TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
"POST: Error <%d> creating path element.",
result);
status = result;
}
- /* if */
+
goto callback;
default:
TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
- "POST: Error <%d> in path record completion.", status);
+ "POST: Error <%d> in path record completion.",
+ status);
goto callback;
- } /* switch */
+ }
return 0;
- callback:
+callback:
+
if (0 < TS_IP2PR_IPOIB_FLAG_GET_FUNC(ipoib_wait)) {
result = ip2pr_path_lookup_complete(ipoib_wait->plid,
@@ -802,12 +815,14 @@
ipoib_wait->arg);
if (0 > result) {
- TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
- "PATH: Error <%d> completing Path Record Lookup.",
- result);
+ TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
+ "FUNC: completion error <%d> <%d:%08x>",
+ result, status, ipoib_wait->dst_addr);
}
+
TS_IP2PR_IPOIB_FLAG_CLR_FUNC(ipoib_wait);
}
+
if (0 < TS_IP2PR_IPOIB_FLAGS_EMPTY(ipoib_wait)) {
result = ip2pr_ipoib_wait_destroy(ipoib_wait,
@@ -823,7 +838,8 @@
/* ip2pr_link_find_complete -- complete the resolution of an ip address */
static s32 ip2pr_link_find_complete(struct ip2pr_ipoib_wait *ipoib_wait,
- s32 status, IP2PR_USE_LOCK use_lock)
+ s32 status,
+ IP2PR_USE_LOCK use_lock)
{
s32 result = 0;
s32 expect;
@@ -838,39 +854,26 @@
status = -EFAULT;
goto done;
}
- /* if */
+
if (0 != status) {
goto done;
}
- /* if */
/*
- * lookup real address
- */
- result = ipoib_get_gid(ipoib_wait->dev, ipoib_wait->hw,
- ipoib_wait->dst_gid);
- if (0 > result) {
-
- TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
- "FUNC: Error <%d> on shadow cache lookup.", result);
- return (0);
- }
- /* if */
- /*
* reset retry counter
*/
ipoib_wait->retry = _tsIp2prLinkRoot.max_retries;
ipoib_wait->prev_timeout = _tsIp2prLinkRoot.retry_timeout;
-
/*
* initiate path record resolution
*/
spin_lock_irqsave(&ipoib_wait->lock, flags);
if (ipoib_wait->state == IP2PR_STATE_ARP_WAIT) {
+
result = tsIbPathRecordRequest(ipoib_wait->ca,
ipoib_wait->hw_port,
- ipoib_wait->src_gid,
- ipoib_wait->dst_gid,
+ ipoib_wait->src_hw.gid.all,
+ ipoib_wait->dst_hw.gid.all,
ipoib_wait->pkey,
TS_IB_PATH_RECORD_FORCE_REMOTE,
(ipoib_wait->prev_timeout * HZ) +
@@ -881,21 +884,24 @@
if (0 != result) {
TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
- "FUNC: Error initiating path record request. <%d>",
+ "FUNC: Path record request error. <%d>",
result);
status = result;
spin_unlock_irqrestore(&ipoib_wait->lock, flags);
goto done;
- } /* if */
+ }
+
ipoib_wait->state = IP2PR_STATE_PATH_WAIT;
- } else {
+ }
+ else {
+
TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
"FUNC: Invalid state <Path wait>");
}
spin_unlock_irqrestore(&ipoib_wait->lock, flags);
return 0;
- done:
+done:
if (0 < TS_IP2PR_IPOIB_FLAG_GET_FUNC(ipoib_wait)) {
result = ip2pr_path_lookup_complete(ipoib_wait->plid,
@@ -906,19 +912,19 @@
if (0 > result) {
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
- "FUNC: Error <%d> completing address resolution. <%d:%08x>",
+ "FUNC: completion error <%d> <%d:%08x>",
result, status, ipoib_wait->dst_addr);
}
- /* if */
+
TS_IP2PR_IPOIB_FLAG_CLR_FUNC(ipoib_wait);
}
- /* if */
+
if (0 < TS_IP2PR_IPOIB_FLAGS_EMPTY(ipoib_wait)) {
-
+
expect = ip2pr_ipoib_wait_destroy(ipoib_wait, use_lock);
TS_EXPECT(MOD_IP2PR, !(0 > expect));
}
- /* if */
+
return 0;
}
@@ -928,19 +934,27 @@
struct neighbour *neigh;
extern struct neigh_table arp_tbl;
- neigh = neigh_lookup(&arp_tbl, &ipoib_wait->dst_addr, ipoib_wait->dev);
- if (neigh) {
+ neigh = neigh_lookup(&arp_tbl,
+ &ipoib_wait->dst_addr,
+ ipoib_wait->dev);
+ if (NULL != neigh) {
+
read_lock_bh(&neigh->lock);
+
*state = neigh->nud_state;
- memcpy(ipoib_wait->hw, neigh->ha, sizeof(ipoib_wait->hw));
+ memcpy(&ipoib_wait->dst_hw,
+ neigh->ha,
+ sizeof(ipoib_wait->dst_hw));
+
read_unlock_bh(&neigh->lock);
- return (0);
- } else {
- memset(ipoib_wait->hw, 0, sizeof(ipoib_wait->hw));
+ return 0;
+ }
+ else {
+ memset(&ipoib_wait->dst_hw, 0, sizeof(ipoib_wait->dst_hw));
*state = 0;
- return (-ENOENT);
+ return -ENOENT;
}
}
@@ -953,30 +967,27 @@
char devname[20];
int i;
+ struct flowi fl = {
+ .oif = ipoib_wait->bound_dev,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = ipoib_wait->dst_addr,
+ .saddr = ipoib_wait->src_addr,
+ .tos = 0,
+ }
+ },
+ .proto = 0,
+ .uli_u = {
+ .ports = {
+ .sport = 0,
+ .dport = 0,
+ }
+ }
+ };
+
TS_CHECK_NULL(ipoib_wait, -EINVAL);
- {
- struct flowi fl = {
- .oif = ipoib_wait->bound_dev, /* oif */
- .nl_u = {
- .ip4_u = {
- .daddr = ipoib_wait->dst_addr, /* dst */
- .saddr = ipoib_wait->src_addr, /* src */
- .tos = 0, /* tos */
- }
- },
- .proto = 0, /* protocol */
- .uli_u = {
- .ports = {
- .sport = 0, /* sport */
- .dport = 0, /* dport */
- }
- }
- };
-
- result = ip_route_output_key(&rt, &fl);
- }
-
+ result = ip_route_output_key(&rt, &fl);
if (0 > result || NULL == rt) {
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
@@ -985,7 +996,6 @@
ipoib_wait->local_rt, ipoib_wait->bound_dev);
return result;
}
- /* if */
/*
* check route flags
*/
@@ -994,11 +1004,11 @@
ip_rt_put(rt);
return -ENETUNREACH;
}
- /* if */
/*
* check that device is IPoIB
*/
- if (NULL == rt->u.dst.neighbour || NULL == rt->u.dst.neighbour->dev) {
+ if (NULL == rt->u.dst.neighbour ||
+ NULL == rt->u.dst.neighbour->dev) {
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
"FIND: No neighbour found for <%08x:%08x>",
@@ -1007,48 +1017,53 @@
result = -EINVAL;
goto error;
}
- /* if */
+
if (0 > TS_IP2PR_IPOIB_DEV_TOPSPIN(rt->u.dst.neighbour->dev) &&
0 == (IFF_LOOPBACK & rt->u.dst.neighbour->dev->flags)) {
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
- "FIND: Destination or neighbour device is not IPoIB. <%s:%08x>",
+ "FIND: Nneighbour device is not IPoIB. <%s:%08x>",
rt->u.dst.neighbour->dev->name,
rt->u.dst.neighbour->dev->flags);
result = -ENETUNREACH;
goto error;
}
- /* if */
+
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
"FIND: Found neighbour. <%08x:%08x:%08x> nud state <%02x>",
rt->rt_src, rt->rt_dst, rt->rt_gateway,
rt->u.dst.neighbour->nud_state);
- ipoib_wait->gw_addr = rt->rt_gateway;
+ ipoib_wait->gw_addr = rt->rt_gateway;
ipoib_wait->src_addr = rt->rt_src;
/*
* device needs to be a valid IB device. Check for loopback.
*/
- ipoib_wait->dev =
- ((0 <
- (IFF_LOOPBACK & rt->u.dst.neighbour->dev->
- flags)) ? ip_dev_find(rt->rt_src) : rt->u.dst.neighbour->dev);
+ if (0 < (IFF_LOOPBACK & rt->u.dst.neighbour->dev->flags)) {
+ ipoib_wait->dev = ip_dev_find(rt->rt_src);
+ }
+ else {
+
+ ipoib_wait->dev = rt->u.dst.neighbour->dev;
+ }
+
if (NULL == ipoib_wait->dev) {
+
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
"network device is null\n",
rt->rt_src, ipoib_wait->dev->name);
result = -EINVAL;
goto error;
}
-
/*
* if loopback, check if src device is an ib device. Allow lo device
*/
if (((0 > TS_IP2PR_IPOIB_DEV_TOPSPIN(ipoib_wait->dev)) &&
(0 != strncmp(ipoib_wait->dev->name, "lo", 2))) &&
(IFF_LOOPBACK & rt->u.dst.neighbour->dev->flags)) {
+
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
"<%08x> is loopback, but is on device %s\n",
rt->rt_src, ipoib_wait->dev->name);
@@ -1061,100 +1076,102 @@
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
"dev->flags 0x%lx means loopback",
ipoib_wait->dev->flags);
-
/*
* Get ipoib interface which is active
*/
- for (i = 0; i < (IP2PR_MAX_HCAS * 2); i++) {
+ for (i = 0, ipoib_wait->dev = NULL;
+ i < (IP2PR_MAX_HCAS * 2);
+ i++) {
+
sprintf(devname, "ib%d", i);
- if (NULL !=
- (ipoib_wait->dev = dev_get_by_name(devname))) {
- if (0 < (IFF_UP & ipoib_wait->dev->flags)) {
- break;
- }
+ ipoib_wait->dev = dev_get_by_name(devname);
+
+ if (NULL != ipoib_wait->dev &&
+ 0 < (IFF_UP & ipoib_wait->dev->flags)) {
+
+ break;
}
}
- if (IP2PR_MAX_HCAS == i)
- ipoib_wait->dev = NULL;
}
- /* if */
/*
* Verify device.
*/
if (NULL == ipoib_wait->dev) {
-
+
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
- "FIND: No device for IB communications <%s:%08x:%08x>",
+ "FIND: No dev for IB communications <%s:%08x:%08x>",
rt->u.dst.neighbour->dev->name,
rt->u.dst.neighbour->dev->flags, rt->rt_src);
result = -EINVAL;
goto error;
}
-
- /* if */
/*
* lookup local information
*/
result = ipoib_device_handle(ipoib_wait->dev,
&ipoib_wait->ca,
&ipoib_wait->hw_port,
- ipoib_wait->src_gid, &ipoib_wait->pkey);
-
+ ipoib_wait->src_hw.gid.all,
+ &ipoib_wait->pkey);
if (0 > result) {
TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
- "FUNC: Error <%d> looking up local device information.",
+ "FUNC: Error <%d> looking up local device info.",
result);
goto error;
}
- /* if */
+
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_INOUT,
- "FIND: hca <%04x> for port <%02x> gidp <%p>",
- ipoib_wait->ca, ipoib_wait->hw_port, ipoib_wait->src_gid);
-
+ "FIND: hca <%04x> for port <%02x> gid <%016llx:%016llx>",
+ ipoib_wait->ca,
+ ipoib_wait->hw_port,
+ be64_to_cpu(ipoib_wait->src_hw.gid.s.high),
+ be64_to_cpu(ipoib_wait->src_hw.gid.s.low));
/*
* if this is a loopback connection, find the local source interface
* and get the associated HW address.
*/
if (rt->u.dst.neighbour->dev->flags & IFF_LOOPBACK) {
- memcpy((char *)ipoib_wait->hw,
- (char *)ipoib_wait->dev->dev_addr,
- sizeof(ipoib_wait->hw));
- } else {
+
+ memcpy(&ipoib_wait->dst_hw,
+ ipoib_wait->dev->dev_addr,
+ sizeof(ipoib_wait->dst_hw));
+
+ goto complete;
+ }
+ /*
+ * Not Lookback. Get the Mac address from arp
+ */
+ result = ip2pr_arp_query(ipoib_wait, &state);
+
+ if (result ||
+ state & NUD_FAILED ||
+ !memcmp(ipoib_wait->dst_hw.gid.all, nullgid, sizeof(nullgid))) {
/*
- * Not Lookback. Get the Mac address from arp
+ * No arp entry. Create a Wait entry and send
+ * Arp request
*/
- result = ip2pr_arp_query(ipoib_wait, &state);
- if ((result) || (state & NUD_FAILED) ||
- ((ipoib_wait->hw[0] == 0) &&
- (ipoib_wait->hw[1] == 0) &&
- (ipoib_wait->hw[2] == 0) &&
- (ipoib_wait->hw[3] == 0) &&
- (ipoib_wait->hw[4] == 0) && (ipoib_wait->hw[5] == 0))) {
- /*
- * No arp entry. Create a Wait entry and send Arp request
- */
- result = ip2pr_ipoib_wait_list_insert(ipoib_wait);
- if (0 > result) {
+ result = ip2pr_ipoib_wait_list_insert(ipoib_wait);
+ if (0 > result) {
- TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE,
- TRACE_FLOW_WARN,
- "FIND: Error <%d> inserting wait for address resolution.",
- result);
- goto error;
- }
- /* if */
- arp_send(ARPOP_REQUEST,
- ETH_P_ARP,
- rt->rt_gateway,
- rt->u.dst.neighbour->dev,
- ipoib_wait->src_addr,
- NULL,
- rt->u.dst.neighbour->dev->dev_addr, NULL);
- return (0);
+ TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
+ "FIND: Error <%d> inserting wait request.",
+ result);
+ goto error;
}
+
+ arp_send(ARPOP_REQUEST,
+ ETH_P_ARP,
+ rt->rt_gateway,
+ rt->u.dst.neighbour->dev,
+ ipoib_wait->src_addr,
+ NULL,
+ rt->u.dst.neighbour->dev->dev_addr,
+ NULL);
+ return 0;
}
+complete:
/*
* We have a valid arp entry or this is a loopback interface.
*/
@@ -1162,17 +1179,17 @@
if (0 > result) {
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
- "FIND: Error <%d> completing address lookup. <%08x:%08x>",
+ "FIND: Error <%d> completing lookup. <%08x:%08x>",
result, ipoib_wait->src_addr, ipoib_wait->dst_addr);
goto error;
- } /* if */
- return (0);
- error:
+ }
+ return 0;
+error:
return result;
}
-/**
+/*
* Arp packet reception for completions
*/
@@ -1194,33 +1211,39 @@
next_wait = ipoib_wait->next;
- if ((ip_addr == ipoib_wait->gw_addr) &&
- (LOOKUP_IP2PR == ipoib_wait->type)) {
+ if (ip_addr != ipoib_wait->gw_addr ||
+ LOOKUP_IP2PR != ipoib_wait->type) {
- spin_lock(&ipoib_wait->lock);
- if ((ipoib_wait->state & IP2PR_STATE_ARP_WAIT) == 0) {
- spin_unlock(&ipoib_wait->lock);
- ipoib_wait = next_wait;
- continue;
- }
+ continue;
+ }
+
+ spin_lock(&ipoib_wait->lock);
+
+ if ((ipoib_wait->state & IP2PR_STATE_ARP_WAIT) == 0) {
+
spin_unlock(&ipoib_wait->lock);
+ ipoib_wait = next_wait;
- TS_IP2PR_IPOIB_FLAG_CLR_TASK(ipoib_wait);
+ continue;
+ }
+ spin_unlock(&ipoib_wait->lock);
- result = ip2pr_link_find_complete(ipoib_wait, 0, 0);
- if (0 > result) {
- TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE,
- TRACE_FLOW_WARN,
- "FIND: Error <%d> completing address lookup. <%08x>",
- result, ipoib_wait->dst_addr);
+ TS_IP2PR_IPOIB_FLAG_CLR_TASK(ipoib_wait);
- result = ip2pr_ipoib_wait_destroy(ipoib_wait,
- IP2PR_LOCK_HELD);
- TS_EXPECT(MOD_IP2PR, !(0 > result));
- }
+ result = ip2pr_link_find_complete(ipoib_wait, 0, 0);
+ if (0 > result) {
+
+ TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_WARN,
+ "FIND: Error <%d> completing lookup. <%08x>",
+ result, ipoib_wait->dst_addr);
+
+ result = ip2pr_ipoib_wait_destroy(ipoib_wait,
+ IP2PR_LOCK_HELD);
+ TS_EXPECT(MOD_IP2PR, !(0 > result));
}
+
ipoib_wait = next_wait;
- } /* while */
+ }
spin_unlock_irqrestore(&_tsIp2prLinkRoot.wait_lock, flags);
return;
@@ -1261,8 +1284,10 @@
* determine if anyone is waiting for this ARP response.
*/
spin_lock_irqsave(&_tsIp2prLinkRoot.wait_lock, flags);
+
for (counter = 0, ipoib_wait = _tsIp2prLinkRoot.wait_list;
- NULL != ipoib_wait; ipoib_wait = ipoib_wait->next) {
+ NULL != ipoib_wait;
+ ipoib_wait = ipoib_wait->next) {
/* skip gid2pr lookup entries */
if (LOOKUP_GID2PR == ipoib_wait->type) {
@@ -1273,7 +1298,8 @@
(ipoib_wait->state & IP2PR_STATE_ARP_WAIT)) {
TS_TRACE(MOD_IP2PR, T_VERY_VERBOSE, TRACE_FLOW_INOUT,
- "RECV: Arp Recv for <%08x>.", arp_hdr->src_ip);
+ "RECV: Arp Recv for <%08x>.",
+ arp_hdr->src_ip);
/*
* remove timer, before scheduling the task.
*/
@@ -1281,8 +1307,9 @@
/*
* save results
*/
- memcpy(ipoib_wait->hw, arp_hdr->src_hw,
- sizeof(ipoib_wait->hw));
+ memcpy(&ipoib_wait->dst_hw,
+ &arp_hdr->src_hw,
+ sizeof(ipoib_wait->dst_hw));
/*
* flags
*/
@@ -1299,13 +1326,14 @@
* Schedule the ARP completion.
*/
if (0 < counter) {
- INIT_WORK(tqp, ip2pr_arp_recv_complete,
+
+ INIT_WORK(tqp,
+ ip2pr_arp_recv_complete,
(void *)(unsigned long)arp_hdr->src_ip);
schedule_work(tqp);
}
- /* if */
- done:
+done:
kfree_skb(skb);
return 0;
}
@@ -1702,7 +1730,7 @@
struct ip2pr_sgid_element *gid_node = NULL;
struct ip2pr_gid_pr_element *prn_elmt;
- if (ip2pr_src_gid_node_get(ipoib_wait->src_gid, &gid_node))
+ if (ip2pr_src_gid_node_get(ipoib_wait->src_hw.gid.all, &gid_node))
return (-EINVAL);
prn_elmt = kmem_cache_alloc(_tsIp2prLinkRoot.gid_pr_cache, SLAB_ATOMIC);
@@ -1849,29 +1877,32 @@
/* if */
switch (status) {
case -ETIMEDOUT:
- if (0 < ipoib_wait->retry--) {
- ipoib_wait->tid = TS_IB_CLIENT_QUERY_TID_INVALID;
- result = tsIbPathRecordRequest(ipoib_wait->ca,
- ipoib_wait->hw_port,
- ipoib_wait->src_gid,
- ipoib_wait->dst_gid,
- ipoib_wait->pkey,
- TS_IB_PATH_RECORD_FORCE_REMOTE,
- TS_IP2PR_DEV_PATH_WAIT,
- 0,
- gid2pr_complete,
- ipoib_wait,
- &ipoib_wait->tid);
- if (0 > result) {
- status = result;
- TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
- "PATH: Error <%d> Completing Path Record Request.",
- result);
- goto callback;
- }
- } else {
+
+ if (0 == ipoib_wait->retry--) {
+
goto callback;
}
+
+ ipoib_wait->tid = TS_IB_CLIENT_QUERY_TID_INVALID;
+ result = tsIbPathRecordRequest(ipoib_wait->ca,
+ ipoib_wait->hw_port,
+ ipoib_wait->src_hw.gid.all,
+ ipoib_wait->dst_hw.gid.all,
+ ipoib_wait->pkey,
+ TS_IB_PATH_RECORD_FORCE_REMOTE,
+ TS_IP2PR_DEV_PATH_WAIT,
+ 0,
+ gid2pr_complete,
+ ipoib_wait,
+ &ipoib_wait->tid);
+ if (0 > result) {
+ status = result;
+ TS_TRACE(MOD_IP2PR, T_VERBOSE, TRACE_FLOW_WARN,
+ "PATH: Path Record Request error. <%d>",
+ result);
+ goto callback;
+ }
+
break;
case 0:
/*
@@ -1948,8 +1979,8 @@
ipoib_wait->ca = gid_node->ca;
ipoib_wait->hw_port = gid_node->port;
ipoib_wait->pkey = pkey;
- memcpy(ipoib_wait->src_gid, src_gid, sizeof(src_gid));
- memcpy(ipoib_wait->dst_gid, dst_gid, sizeof(dst_gid));
+ memcpy(ipoib_wait->src_hw.gid.all, src_gid, sizeof(src_gid));
+ memcpy(ipoib_wait->dst_hw.gid.all, dst_gid, sizeof(dst_gid));
result = ip2pr_ipoib_wait_list_insert(ipoib_wait);
if (0 > result) {
More information about the openib-general mailing list