[openib-general] [PATCH] NOARP Device Support in the CMA

Tom Tucker tom at opengridcomputing.com
Fri Feb 10 07:36:00 PST 2006


This patch adds support for devices that do ARP internally. The
patch checks the flags in the netdevice during ARP resolution
processing to see if it supports ARP. If it does not, it will 
return 'done' up the stack until it hits the CMA where a callback
will be generated on the CMA workqueue thread. 

I tested this with the 'krping' application on mthca. This can't 
be tested with a device that actually does this (AMSO) until we
get this driver dropped in the trunk. It has been tested in the
iWARP branch however with both IB and iWARP.

Signed-off-by: Tom Tucker <tom at opengridcomputing.com>

Index: addr.c
===================================================================
--- addr.c	(revision 5356)
+++ addr.c	(working copy)
@@ -36,6 +36,7 @@
 
 #include <linux/inetdevice.h>
 #include <linux/workqueue.h>
+#include <linux/if_arp.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
 #include <net/route.h>
@@ -163,6 +164,12 @@
 	if (ret)
 		goto out;
 
+	/* If the device does ARP internally, return 'done' */
+	if (rt->idev->dev->flags & IFF_NOARP) {
+		copy_addr(addr, rt->idev->dev, NULL);
+		return 1;
+	}
+
 	neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev);
 	if (!neigh) {
 		ret = -ENODATA;
@@ -288,6 +295,10 @@
 		req->timeout = jiffies;
 		queue_req(req);
 		break;
+	case 1:
+		ret = req->status;
+		kfree(req);
+		break;
 	case -ENODATA:
 		req->timeout = msecs_to_jiffies(timeout_ms) + jiffies;
 		queue_req(req);
Index: cma.c
===================================================================
--- cma.c	(revision 5356)
+++ cma.c	(working copy)
@@ -1315,6 +1315,27 @@
 		ret = rdma_resolve_ip(src_addr, dst_addr,
 				      &id->route.addr.dev_addr,
 				      timeout_ms, addr_handler, id_priv);
+	if (ret == 1) {
+		/* Already resolved, schedule the addr_handler on the 
+		 * work queue.
+		 */
+		struct cma_work *work = kmalloc(sizeof *work, GFP_KERNEL);
+		if (!work)
+			return -ENOMEM;
+		ret = cma_acquire_dev(id_priv);
+		if (ret) {
+			kfree(work);
+			goto err;
+		}
+		work->id = id_priv;
+		INIT_WORK(&work->work, cma_work_handler, work);
+		work->old_state = CMA_ADDR_QUERY;
+		work->new_state = CMA_ADDR_RESOLVED;
+		work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
+		queue_work(rdma_wq, &work->work);
+		return 0;
+	}
+
 	if (ret)
 		goto err;
 




More information about the general mailing list