[openib-general] [CM]question about creating a Servcie

Ian Jiang ianjiang.ict at gmail.com
Mon Feb 27 18:38:22 PST 2006


Hi all,
I am trying to use the CM mechanism in the kernal space and  come across  a
problem while creating a service:

[IB_CM][ib_cm_service_create][drivers/infiniband/ib_cm/cm_service_table.c:198]Conflict
between 000000000000b0e0/ffffffffffffffff and
0000000000000000/ffffffffffff0000

I am not very clear of the rules while using the Service ID and the Service
Mask, could anybody give an explaination?
Thanks very much and here are a piece of my code and the relative code in
IBGD-1.8.0:

================================================================
#define TS_KVAPITEST_MSG_SERVICE_ID_VALUE (0xb0e0ULL)
#define TS_KVAPITEST_MSG_SERVICE_ID_MASK  (0xFFFFFFFFFFFF0000ULL)

    res = ib_cm_listen(TS_KVAPITEST_MSG_SERVICE_ID_VALUE,
            TS_KVAPITEST_MSG_SERVICE_ID_MASK,
            params_p->ib_res.call_back_func,
            params_p->ib_res.arg,
            &params_p->ib_res.listen_hndl);

================================================================
int ib_cm_service_create(tTS_IB_SERVICE_ID  service_id,
             tTS_IB_SERVICE_ID  service_mask,
             struct ib_cm_service **service)
{
    struct ib_cm_tree_node *node;
    struct ib_cm_tree_node *new_node = NULL;
    struct ib_cm_tree_node *new_parent = NULL;
    u64 bit, mask;
    int child_num;
    int ret;
    TS_WINDOWS_SPINLOCK_FLAGS

        *service = NULL;

    new_node   = kmem_cache_alloc(node_cache,    GFP_KERNEL);
    new_parent = kmem_cache_alloc(node_cache,    GFP_KERNEL);
    *service   = kmem_cache_alloc(service_cache, GFP_KERNEL);

    if (!new_node || !new_parent || !*service) {
        ret = -ENOMEM;
        goto out_free;
    }

    new_node->id          = service_id;
    new_node->mask        = service_mask;
    new_node->bit         = 0;
    new_node->ptr.service = *service;

    spin_lock(&tree_lock);

    node = ib_cm_tree_search(service_id, service_mask);

    if (node) {
        if ((service_mask & node->id) == (node->mask & service_id)) {
            TS_REPORT_WARN(MOD_IB_CM,
                       "Conflict between %016" TS_U64_FMT "x/%016"
TS_U64_FMT "x "
                       "and %016" TS_U64_FMT "x/%016" TS_U64_FMT "x",
                       node->id, node->mask,
                       service_id, service_mask);
            ret = -EADDRINUSE;
            goto out;
        }

        /* find the first bit where we're different -- if there isn't one,
           then we conflict with the previous service */
        for (mask = 0x0ULL, bit = 0x8000000000000000ULL;
             bit;
             mask |= bit, bit >>= 1) {
            if ((bit & service_id) != (bit & node->id))
                break;
        }

        if (!bit || mask >= node->mask) {
            TS_REPORT_WARN(MOD_IB_CM,
                       "Couldn't find a difference: %016" TS_U64_FMT
"x/%016" TS_U64_FMT "x "
                       "and %016" TS_U64_FMT "x/%016" TS_U64_FMT "x",
                       node->id, node->mask,
                       service_id, service_mask);
            ret = -EINVAL;
            goto out;
        }

        new_parent->id        = service_id & mask;
        new_parent->mask      = mask;
        new_parent->bit       = bit;
        new_parent->parent    = node->parent;
        new_parent->child_num = node->child_num;
        if (node->parent) {
            node->parent->ptr.child[node->child_num] = new_parent;
        } else {
            service_tree = new_parent;
        }

        child_num = !!(bit & service_id);
        new_parent->ptr.child[ child_num] = new_node;
        new_node->parent                  = new_parent;
        new_node->child_num               = child_num;
        new_parent->ptr.child[!child_num] = node;
        node->parent                      = new_parent;
        node->child_num                   = !child_num;
    } else {
        if (service_tree) {
            TS_REPORT_WARN(MOD_IB_CM,
                       "No parent found but tree not empty!");
            ret = -EINVAL;
            goto out;
        }

        /* Don't need the new parent node for the first service we add */
        kmem_cache_free(node_cache, new_parent);

        service_tree        = new_node;
        new_node->parent    = NULL;
    }

    (*service)->node    = new_node;
    (*service)->freeing = 0;
    init_MUTEX_LOCKED(&(*service)->mutex);

    atomic_set(&(*service)->waiters, 0);

    spin_unlock(&tree_lock);

    return 0;

 out:
    spin_unlock(&tree_lock);

 out_free:
    if (new_node)
        kmem_cache_free(node_cache, new_node);

    if (new_parent)
        kmem_cache_free(node_cache, new_parent);

    if (*service)
        kmem_cache_free(service_cache, *service);

    return ret;
}


--
Ian Jiang
ianjiang.ict at gmail.com

Laboratory of Spatial Information Technology
Division of System Architecture
Institute of Computing Technology
Chinese Academy of Sciences
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/general/attachments/20060228/dd87bb89/attachment.html>


More information about the general mailing list