Various AT changes including:
Get API in line with changes on shahar-ibat branch
Integrate various changes from shahar-ibat branch which apply to the
"level of functionality" originally implemented (e.g. no Service Record
support)
Fix a couple of minor bugs found by code inspection
Better debug support

Note that this does not fix the slab corruption problem :-(

Signed-off-by: Hal Rosenstock <[EMAIL PROTECTED]>

Index: ib_at.h
===================================================================
--- ib_at.h     (revision 2331)
+++ ib_at.h     (working copy)
@@ -30,25 +30,28 @@
  * SOFTWARE.
  *
  *
- * $Id:$
+ * $Id$
  */
 
 #if !defined( IB_AT_H )
 #define IB_AT_H
 
+#include <ib_verbs.h>
+#include <ib_sa.h>
+
 enum ib_at_multipathing_type {
        IB_AT_PATH_SAME_PORT    = 0,
-       IB_AT_PATH_SAME_HCA     = 1,            /* but different ports if 
applicable */
-       IB_AT_PATH_SAME_SYSTEM  = 2,            /* but different ports if 
applicable */
+       IB_AT_PATH_SAME_HCA     = 1,    /* but different ports if applicable */
+       IB_AT_PATH_SAME_SYSTEM  = 2,    /* but different ports if applicable */
        IB_AT_PATH_INDEPENDENT_HCA = 3,
-       IB_AT_PATH_SRC_ROUTE    = 4,            /* application controlled 
multipathing */
+       IB_AT_PATH_SRC_ROUTE    = 4,    /* application controlled multipathing 
*/
 };
 
 enum ib_at_route_flags {
-       IB_AT_ROUTE_USE_DEFAULTS = 0,
-       IB_AT_ROUTE_FORCE_ATS,
-       IB_AT_ROUTE_FORCE_ARP,
-       IB_AT_ROUTE_FORCE_RESOLVE,
+       IB_AT_ROUTE_USE_DEFAULTS        = 0,
+       IB_AT_ROUTE_FORCE_ATS           = 1,
+       IB_AT_ROUTE_FORCE_ARP           = 2,
+       IB_AT_ROUTE_FORCE_RESOLVE       = 4,
 };
 
 struct ib_at_path_attr {
@@ -169,7 +172,7 @@
  * See ib_at_completion structure documentation for asynchronous
  * operation details.
  */
-int ib_at_ips_by_gid(union ib_gid gid, u32 *dst_ips, int nips,
+int ib_at_ips_by_gid(union ib_gid *gid, u32 *dst_ips, int nips,
                    struct ib_at_completion *async_comp);
 
 /**
@@ -208,7 +211,7 @@
  * @req_id: asynchronous request ID ib_at_op_status
  *
  * Return non-negative ib_at_op_status value, 
- * or -EINVAL if the reqest ID is invalid.
+ * or -EINVAL if the request ID is invalid.
  */
 int ib_at_status(u64 req_id);
 
Index: at.c
===================================================================
--- at.c        (revision 2331)
+++ at.c        (working copy)
@@ -30,7 +30,7 @@
  * SOFTWARE.
  *
  *
- * $Id:$
+ * $Id$
  */
 
 #include <linux/module.h>
@@ -118,7 +118,7 @@
        int sa_id;
 };
 
-static struct async pending_reqs;      /* dummy head for cyclic list */
+struct async pending_reqs;     /* dummy head for cyclic list */
 
 struct ib_at_src {
        u32 ip;
@@ -158,7 +158,6 @@
 static void path_req_complete(int stat, struct ib_sa_path_rec *ret, void *ctx);
 static int resolve_path(struct path_req *req);
 
-
 static int resolve_ip(struct ib_at_src *src, u32 dst_ip, u32 src_ip,
                        int tos, union ib_gid *dgid)
 {
@@ -254,7 +253,7 @@
        src->dev = priv->ca;
        src->port = priv->port;
        src->pkey = cpu_to_be16(priv->pkey);
-       memcpy(&src->gid, (ipoib_dev->dev_addr + 4), sizeof(src->gid));
+       memcpy(&src->gid, ipoib_dev->dev_addr + 4, sizeof(src->gid));
 
        if (!dgid)
                return 0;
@@ -264,7 +263,7 @@
         * the IB device which was found.
         */
        if (rt->u.dst.neighbour->dev->flags & IFF_LOOPBACK) {
-               memcpy(dgid, (ipoib_dev->dev_addr + 4),
+               memcpy(dgid, ipoib_dev->dev_addr + 4,
                       sizeof(union ib_gid));
 
                return 1;
@@ -272,7 +271,7 @@
 
        if ((NUD_CONNECTED|NUD_DELAY|NUD_PROBE) &
            rt->u.dst.neighbour->nud_state) {
-               memcpy(dgid, (rt->u.dst.neighbour->ha + 4),
+               memcpy(dgid, rt->u.dst.neighbour->ha + 4,
                       sizeof(union ib_gid));
 
                return 1;
@@ -285,9 +284,17 @@
 
 static u64 alloc_req_id(void)
 {
-       static u64 req_id = 1;
+       static u64 req_id = 0;
+       u64 new_id;
+       unsigned long flags;
 
-       return ++req_id;
+       spin_lock_irqsave(&pending_reqs.lock, flags);
+       new_id = ++req_id;
+       if (!new_id)
+               new_id = ++req_id;
+       spin_unlock_irqrestore(&pending_reqs.lock, flags);
+
+       return new_id;
 }
 
 static void req_init(struct async *pend, void *data, int nelem, int type,
@@ -361,7 +368,7 @@
 {
        struct async *pend = v;
 
-       DEBUG("complete req %p\n", pend);
+       DEBUG("complete pend %p", pend);
 
        pend->comp.fn(pend->comp.req_id, pend->comp.context, pend->nelem);
 
@@ -373,20 +380,23 @@
        struct async **rr, *waiting;
        unsigned long flags = 0;
 
-       DEBUG("pend %p nrec %d", pend, nrec);
+       DEBUG("pend %p nrec %d async %p", pend, nrec, q);
 
        if (pend->status != IB_AT_STATUS_PENDING)
-               WARN("pend %p already completed??", pend);
+               WARN("pend %p already completed? status %d", pend, 
pend->status);
 
        pend->status = nrec < 0 ? IB_AT_STATUS_ERROR : IB_AT_STATUS_COMPLETED;
 
-       if (pend->sa_query)
+       if (pend->sa_query) {
                ib_sa_cancel_query(pend->sa_id, pend->sa_query);
+               pend->sa_query = NULL;
+       }
 
        if (q)
                spin_lock_irqsave(&q->lock, flags);
 
        if (pend->parent) {
+               DEBUG("pend->parent %p", pend->parent);
                for (rr = &pend->parent->waiting; *rr; rr = &(*rr)->waiting)
                        if (*rr == pend) {
                                *rr = (*rr)->waiting;
@@ -476,11 +486,13 @@
        unsigned long flags;
        struct async *a;
 
-       DEBUG("lookup in q %p req %p", q, new);
+       DEBUG("lookup in q %p pending %p", q, new);
        spin_lock_irqsave(&q->lock, flags);
-       for (a = q->next; a != q; a = a->next)
+       for (a = q->next; a != q; a = a->next) {
+               DEBUG("%d %d", a->type, type);
                if (a->type == type && same_fn(a, new))
                        break;
+       }
 
        spin_unlock_irqrestore(&q->lock, flags);
        return a == q ? NULL : a;
@@ -574,13 +586,14 @@
        DEBUG("req %p", req);
 
        if (req->pend.parent) {
-               WARN("path_req_complete for child req %p???", req);
+               WARN("for child req %p???", req);
                return;
        }
 
        if (status) {
-               DEBUG("timed out - check if should retry");
-               if (jiffies - req->pend.start < IB_AT_REQ_TIMEOUT)
+               DEBUG("status %d - check if should retry", status);
+               if (status == -ETIMEDOUT &&
+                   jiffies - req->pend.start < IB_AT_REQ_TIMEOUT)
                        resolve_path(req);
                else
                        req_end(&req->pend, -ETIMEDOUT, &pending_reqs);
@@ -605,6 +618,7 @@
 {
        struct async *pend, *next;
        struct route_req *req;
+       struct path_req *preq;
        unsigned long flags;
 
        DEBUG("start sweeping");
@@ -613,18 +627,36 @@
        for (pend = pending_reqs.next; pend != &pending_reqs; pend = next) {
                next = pend->next;
 
-               req = container_of(pend, struct route_req, pend);
+               switch (pend->type) {
+               case IBAT_REQ_ARP:
+               case IBAT_REQ_ATS:
+                       req = container_of(pend, struct route_req, pend);
 
-               DEBUG("examining route req %p pend %p", req, pend);
-               if (jiffies > (pend->start + IB_AT_REQ_TIMEOUT)) {
-                       DEBUG("req delete <%d.%d.%d.%d> <%lu:%lu>",
-                            (req->dst_ip & 0x000000ff),
-                            (req->dst_ip & 0x0000ff00) >> 8,
-                            (req->dst_ip & 0x00ff0000) >> 16,
-                            (req->dst_ip & 0xff000000) >> 24,
-                            jiffies, pend->start);
+                       DEBUG("examining route req %p pend %p", req, pend);
+                       if (jiffies > pend->start + IB_AT_REQ_TIMEOUT) {
+                               DEBUG("req delete <%d.%d.%d.%d> <%lu:%lu>",
+                                    (req->dst_ip & 0x000000ff),
+                                    (req->dst_ip & 0x0000ff00) >> 8,
+                                    (req->dst_ip & 0x00ff0000) >> 16,
+                                    (req->dst_ip & 0xff000000) >> 24,
+                                    jiffies, pend->start);
 
-                       req_end(pend, -ETIMEDOUT, NULL);
+                               req_end(pend, -ETIMEDOUT, NULL);
+                       }
+                       break;
+               case IBAT_REQ_PATHREC:
+                       preq = container_of(pend, struct path_req, pend);
+
+                       DEBUG("examining path req %p pend %p", preq, pend);
+                       if (jiffies > pend->start + IB_AT_REQ_TIMEOUT) {
+                               DEBUG("req delete path <%lu:%lu>",
+                                     jiffies, pend->start);
+
+                               req_end(pend, -ETIMEDOUT, NULL);
+                       }
+                       break;
+               default:
+                       WARN("unknown async req type %d", pend->type);
                }
        }
 
@@ -651,7 +683,7 @@
 
        if (req->pend.type == IBAT_REQ_ATS) {
                WARN("ATS - not yet");
-               return 0;
+               return -1;      /* 0 when supported */
        }
 
        WARN("bad req %p type %d", req, req->pend.type);
@@ -666,32 +698,31 @@
                .dgid = req->rt.dgid,
                .sgid = req->rt.sgid,
        };
-       int r;
 
        if (req->pend.type != IBAT_REQ_PATHREC) {
                WARN("bad req %p type %d", req, req->pend.type);
                return -1;
        }
 
-       r = ib_sa_path_rec_get(req->rt.out_dev,
-                               req->rt.out_port,
-                               &rec,
-                               (IB_SA_PATH_REC_DGID |
-                                       IB_SA_PATH_REC_SGID |
-                                       IB_SA_PATH_REC_PKEY |
-                                       IB_SA_PATH_REC_NUMB_PATH),
-                               req->pend.timeout_ms,
-                               GFP_KERNEL,
-                               path_req_complete,
-                               req,
-                               &req->pend.sa_query);
+       req->pend.sa_id = ib_sa_path_rec_get(req->rt.out_dev,
+                                            req->rt.out_port,
+                                           &rec,
+                                           (IB_SA_PATH_REC_DGID |
+                                            IB_SA_PATH_REC_SGID |
+                                            IB_SA_PATH_REC_PKEY |
+                                            IB_SA_PATH_REC_NUMB_PATH),
+                                            req->pend.timeout_ms,
+                                            GFP_KERNEL,
+                                            path_req_complete,
+                                            req,
+                                           &req->pend.sa_query);
 
-       if (r < 0)
-               return r;
+       if (req->pend.sa_id < 0) {
+               WARN("ib_sa_path_rec_get %d", req->pend.sa_id);
+               return req->pend.sa_id;
+       }
 
        req->pend.timeout_ms <<= 1;             /* exponential backoff */
-       req->pend.sa_id = r;
-
        return 0;
 }
 
@@ -716,10 +747,12 @@
 
        spin_lock_irqsave(&q->lock, flags);
        for (a = q->next; a != q; a = a->next) {
+               DEBUG("a %p", a);
                if (a->type != IBAT_REQ_ARP)
                        continue;
 
                req = container_of(a, struct route_req, pend);
+               DEBUG("req %p", req);
 
                if (arp->op == __constant_htons(ARPOP_REPLY)) {
                        if (arp->dst_ip == req->dst_ip)
@@ -751,7 +784,6 @@
         * queue IB arp packet onto work queue.
         */
        DEBUG("recv IB ARP - queue work");
-
        work = kmalloc(sizeof(*work), GFP_ATOMIC);
        if (!work)
                goto done;
@@ -763,7 +795,6 @@
 
 done:
        kfree_skb(skb);
-
        return 0;
 }
 
@@ -796,17 +827,20 @@
 
        r = resolve_ip(&rreq->src, dst_ip, src_ip, tos, &rreq->dgid);
        if (r < 0) {
+               DEBUG("resolve_ip r < 0 free req %p", rreq);
                kmem_cache_free(route_req_cache, rreq);
                return r;
        }
 
        if (r > 0) {
                route_req_output(rreq, ib_route);
+               DEBUG("resolve_ip r > 0 free req %p", rreq);
                kmem_cache_free(route_req_cache, rreq);
                return 1;
        }       
 
        if (!async_comp) {
+               DEBUG("!async_comp free req %p", rreq);
                kmem_cache_free(route_req_cache, rreq);
                return -EWOULDBLOCK;
        }
@@ -855,6 +889,7 @@
        */
 
        if (!async_comp) {
+               DEBUG("!async_comp free req %p", preq);
                kmem_cache_free(path_req_cache, preq);
                return -EWOULDBLOCK;
        }
@@ -871,7 +906,7 @@
 }
 EXPORT_SYMBOL(ib_at_paths_by_route);
 
-int ib_at_ips_by_gid(union ib_gid gid, u32 *dst_ips, int nips,
+int ib_at_ips_by_gid(union ib_gid *gid, u32 *dst_ips, int nips,
                    struct ib_at_completion *async_comp)
 {
        return -1;      /* FIXME: not implemented yet */
@@ -910,7 +945,7 @@
                a->next->prev = child;
                a->next = child;
 
-               a->waiting = NULL;      /* clear to avoid cancelling childs */
+               a->waiting = NULL;      /* clear to avoid cancelling children */
        }
 
        req_end(a, -EINTR, NULL);
@@ -950,7 +985,16 @@
 
        DEBUG("IB AT services init");
 
-       route_req_cache = kmem_cache_create("ib_at_route_reqs",
+       /*
+        * init pending lists' dummies.
+        */
+       pending_reqs.next = pending_reqs.prev = &pending_reqs;
+       spin_lock_init(&pending_reqs.lock);
+
+       /*
+        * Init memory pools
+        */
+       route_req_cache = kmem_cache_create("ib_at_routes",
                                        sizeof(struct route_req),
                                        0, SLAB_HWCACHE_ALIGN,
                                        NULL, NULL);
@@ -960,7 +1004,7 @@
                goto err_route;
        }
 
-       path_req_cache = kmem_cache_create("ib_at_path_reqs",
+       path_req_cache = kmem_cache_create("ib_at_paths",
                                        sizeof(struct path_req),
                                        0, SLAB_HWCACHE_ALIGN,
                                        NULL, NULL);
@@ -970,6 +1014,9 @@
                goto err_path;
        }
 
+       /*
+        * Init ib at worker thread and queue
+        */
        ib_at_wq = create_workqueue("ib_at_wq");
        if (!ib_at_wq) {
                WARN("Failed to allocate IB AT wait queue.");
@@ -979,6 +1026,7 @@
        
        INIT_WORK(&ib_at_timer, ib_at_sweep, NULL);
        queue_delayed_work(ib_at_wq, &ib_at_timer, IB_AT_SWEEP_INTERVAL);
+
        /*
         * install device for receiving ARP packets in parallel to the normal
         * Linux ARP, this will be the SDP notifier that an ARP request has



_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to