[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