OK, here's my latest set of patches. With these changes, userspace
verbs work for me (tested between my one ipath system and a system
with a Mellanox HCA).
I do see a few anomalies, but I don't think they're caused by the
generic uverbs changes I made, since I'm not touching the ipath driver:
- ibv_rc_pingpong is very very slow (like 26 Mb/sec with default params).
- ibv_rc_pingpong on loopback doesn't work:
$ ibv_rc_pingpong & sleep 1 && ibv_rc_pingpong localhost
[2] 15790
local address: LID 0x000a, QPN 0x00006c, PSN 0xf277e7
local address: LID 0x000a, QPN 0x00006d, PSN 0xdcd50e
remote address: LID 0x000a, QPN 0x00006d, PSN 0xdcd50e
remote address: LID 0x000a, QPN 0x00006c, PSN 0xf277e7
Failed status 12 for wr_id 2
- ibv_ud_pingpong on loopback doesn't work either:
$ ibv_ud_pingpong & sleep 1 && ibv_ud_pingpong localhost
[3] 15800
local address: LID 0x000a, QPN 0x00006e, PSN 0xa622b2
local address: LID 0x000a, QPN 0x00006f, PSN 0x350102
remote address: LID 0x000a, QPN 0x00006f, PSN 0x350102
remote address: LID 0x000a, QPN 0x00006e, PSN 0xa622b2
Couldn't post send
As a bonus, I'm throwing in a patch for libipathoib to fix the RPM
build on Fedora Core 4, and delete the unused ipathoib-abi.h header.
(You'll have to do svn rm yourself to completely kill the file, if you
apply this patch).
BTW, I think it would be a good idea to rename libipathoib to
something like "libipath" (or "libipathverbs" or whatever). I don't
think we want to put "oib" or "openib" in the name, since in the long
run we're just going to be part of the standard Linux IB (or RDMA)
drivers.
- R.
Index: infiniband/core/uverbs_cmd.c
===================================================================
--- infiniband/core/uverbs_cmd.c (revision 3742)
+++ infiniband/core/uverbs_cmd.c (working copy)
@@ -699,24 +699,25 @@ ssize_t ib_uverbs_poll_cq(struct ib_uver
}
resp->count = ib_poll_cq(cq, cmd.ne, wc);
- for(i = 0; i < cmd.ne; i++) {
- resp->wc[i].wr_id = wc[i].wr_id;
- resp->wc[i].status = wc[i].status;
- resp->wc[i].opcode = wc[i].opcode;
- resp->wc[i].vendor_err = wc[i].vendor_err;
- resp->wc[i].byte_len = wc[i].byte_len;
- resp->wc[i].imm_data = wc[i].imm_data;
- resp->wc[i].qp_num = wc[i].qp_num;
- resp->wc[i].src_qp = wc[i].src_qp;
- resp->wc[i].wc_flags = wc[i].wc_flags;
- resp->wc[i].pkey_index = wc[i].pkey_index;
- resp->wc[i].slid = wc[i].slid;
- resp->wc[i].sl = wc[i].sl;
+
+ for (i = 0; i < resp->count; i++) {
+ resp->wc[i].wr_id = wc[i].wr_id;
+ resp->wc[i].status = wc[i].status;
+ resp->wc[i].opcode = wc[i].opcode;
+ resp->wc[i].vendor_err = wc[i].vendor_err;
+ resp->wc[i].byte_len = wc[i].byte_len;
+ resp->wc[i].imm_data = wc[i].imm_data;
+ resp->wc[i].qp_num = wc[i].qp_num;
+ resp->wc[i].src_qp = wc[i].src_qp;
+ resp->wc[i].wc_flags = wc[i].wc_flags;
+ resp->wc[i].pkey_index = wc[i].pkey_index;
+ resp->wc[i].slid = wc[i].slid;
+ resp->wc[i].sl = wc[i].sl;
resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
- resp->wc[i].port_num = wc[i].port_num;
+ resp->wc[i].port_num = wc[i].port_num;
}
- if (copy_to_user((void __user *)cmd.response, resp, rsize))
+ if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
ret = -EFAULT;
out:
@@ -741,15 +742,12 @@ ssize_t ib_uverbs_req_notify_cq(struct i
down(&ib_uverbs_idr_mutex);
cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
- if (!cq || cq->uobject->context != file->ucontext)
- goto out;
-
- ib_req_notify_cq(cq, cmd.solicited ? IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
-
- ret = in_len;
-
-out:
+ if (cq && cq->uobject->context == file->ucontext) {
+ ib_req_notify_cq(cq, cmd.solicited ? IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
+ ret = in_len;
+ }
up(&ib_uverbs_idr_mutex);
+
return ret;
}
@@ -1097,196 +1095,277 @@ ssize_t ib_uverbs_post_send(struct ib_uv
{
struct ib_uverbs_post_send cmd;
struct ib_uverbs_post_send_resp resp;
- struct ib_uverbs_send_wr *m_wr, *j;
- struct ib_send_wr *wr, *i, *bad_wr;
- struct ib_sge *s;
+ struct ib_uverbs_send_wr *user_wr;
+ struct ib_send_wr *wr = NULL, *last, *next, *bad_wr;
struct ib_qp *qp;
- int size;
- int count;
+ int i, sg_ind;
ssize_t ret = -EINVAL;
- resp.bad_wr = 0;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ if (in_len < sizeof cmd + cmd.wqe_size * cmd.wr_count +
+ cmd.sge_count * sizeof (struct ib_uverbs_sge))
+ return -EINVAL;
+
+ if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr))
+ return -EINVAL;
+
+ user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL);
+ if (!user_wr)
+ return -ENOMEM;
+
down(&ib_uverbs_idr_mutex);
qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
if (!qp || qp->uobject->context != file->ucontext)
goto out;
- size = (cmd.wr_count * sizeof *wr) + (cmd.sge_count * sizeof *s);
- m_wr = kmalloc(size, GFP_KERNEL);
- if (!m_wr) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (copy_from_user(m_wr, (void __user *)cmd.wr, size)) {
- ret = -EFAULT;
- goto wrout;
- }
-
- wr = kmalloc(cmd.wr_count * sizeof *wr, GFP_KERNEL);
- if (!wr) {
- ret = -ENOMEM;
- goto wrout;
- }
+ sg_ind = 0;
+ last = NULL;
+ for (i = 0; i < cmd.wr_count; ++i) {
+ if (copy_from_user(user_wr,
+ buf + sizeof cmd + i * cmd.wqe_size,
+ cmd.wqe_size)) {
+ ret = -EFAULT;
+ goto out;
+ }
- s = (struct ib_sge *)(m_wr + cmd.wr_count);
+ if (user_wr->num_sge + sg_ind > cmd.sge_count) {
+ ret = -EINVAL;
+ goto out;
+ }
- i = wr;
- j = m_wr;
- count = 0;
- while (count++ < cmd.wr_count) {
- struct ib_send_wr *t = i++;
- struct ib_uverbs_send_wr *u = j++;
+ next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
+ user_wr->num_sge * sizeof (struct ib_sge),
+ GFP_KERNEL);
+ if (!next) {
+ ret = -ENOMEM;
+ goto out;
+ }
- if (count < cmd.wr_count)
- t->next = i;
+ if (!last)
+ wr = next;
else
- t->next = NULL;
+ last->next = next;
+ last = next;
- t->wr_id = u->wr_id;
- t->num_sge = u->num_sge;
- t->opcode = u->opcode;
- t->send_flags = u->send_flags;
- t->imm_data = u->imm_data;
+ next->next = NULL;
+ next->wr_id = user_wr->wr_id;
+ next->num_sge = user_wr->num_sge;
+ next->opcode = user_wr->opcode;
+ next->send_flags = user_wr->send_flags;
+ next->imm_data = user_wr->imm_data;
if (qp->qp_type == IB_QPT_UD) {
- t->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, u->wr.ud.ah);
- if (!t->wr.ud.ah)
- goto kwrout;
- t->wr.ud.remote_qpn = u->wr.ud.remote_qpn;
- t->wr.ud.remote_qkey = u->wr.ud.remote_qkey;
+ next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr,
+ user_wr->wr.ud.ah);
+ if (!next->wr.ud.ah) {
+ ret = -EINVAL;
+ goto out;
+ }
+ next->wr.ud.remote_qpn = user_wr->wr.ud.remote_qpn;
+ next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey;
} else {
- switch (t->opcode) {
+ switch (next->opcode) {
case IB_WR_RDMA_WRITE:
case IB_WR_RDMA_WRITE_WITH_IMM:
case IB_WR_RDMA_READ:
- t->wr.rdma.remote_addr = u->wr.rdma.remote_addr;
- t->wr.rdma.rkey = u->wr.rdma.rkey;
+ next->wr.rdma.remote_addr =
+ user_wr->wr.rdma.remote_addr;
+ next->wr.rdma.rkey =
+ user_wr->wr.rdma.rkey;
break;
case IB_WR_ATOMIC_CMP_AND_SWP:
case IB_WR_ATOMIC_FETCH_AND_ADD:
- t->wr.atomic.remote_addr =
- u->wr.atomic.remote_addr;
- t->wr.atomic.compare_add =
- u->wr.atomic.compare_add;
- t->wr.atomic.swap = u->wr.atomic.swap;
- t->wr.atomic.rkey = u->wr.atomic.rkey;
+ next->wr.atomic.remote_addr =
+ user_wr->wr.atomic.remote_addr;
+ next->wr.atomic.compare_add =
+ user_wr->wr.atomic.compare_add;
+ next->wr.atomic.swap = user_wr->wr.atomic.swap;
+ next->wr.atomic.rkey = user_wr->wr.atomic.rkey;
break;
default:
break;
}
}
- if (t->num_sge) {
- t->sg_list = s;
- s += t->num_sge;
+ if (next->num_sge) {
+ next->sg_list = (void *) next +
+ ALIGN(sizeof *next, sizeof (struct ib_sge));
+ if (copy_from_user(next->sg_list,
+ buf + sizeof cmd +
+ cmd.wr_count * cmd.wqe_size +
+ sg_ind * sizeof (struct ib_sge),
+ next->num_sge * sizeof (struct ib_sge))) {
+ ret = -EFAULT;
+ goto out;
+ }
+ sg_ind += next->num_sge;
} else
- t->sg_list = NULL;
+ next->sg_list = NULL;
}
+ resp.bad_wr = 0;
ret = qp->device->post_send(qp, wr, &bad_wr);
- resp.bad_wr = ret ? (bad_wr - wr) + 1 : 0;
-
-kwrout:
- kfree(wr);
+ if (ret)
+ for (next = wr; next; next = next->next) {
+ ++resp.bad_wr;
+ if (next == bad_wr)
+ break;
+ }
-wrout:
- kfree(m_wr);
+ if (copy_to_user((void __user *) (unsigned long) cmd.response,
+ &resp, sizeof resp))
+ ret = -EFAULT;
out:
up(&ib_uverbs_idr_mutex);
- if (copy_to_user((void __user *) (unsigned long) cmd.response,
- &resp, sizeof resp))
- ret = -EFAULT;
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
+ kfree(user_wr);
return ret ? ret : in_len;
}
+static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf,
+ int in_len,
+ u32 wr_count,
+ u32 sge_count,
+ u32 wqe_size)
+{
+ struct ib_uverbs_recv_wr *user_wr;
+ struct ib_recv_wr *wr = NULL, *last, *next;
+ int sg_ind;
+ int i;
+ int ret;
+
+ if (in_len < wqe_size * wr_count +
+ sge_count * sizeof (struct ib_uverbs_sge))
+ return ERR_PTR(-EINVAL);
+
+ if (wqe_size < sizeof (struct ib_uverbs_recv_wr))
+ return ERR_PTR(-EINVAL);
+
+ user_wr = kmalloc(wqe_size, GFP_KERNEL);
+ if (!user_wr)
+ return ERR_PTR(-ENOMEM);
+
+ sg_ind = 0;
+ last = NULL;
+ for (i = 0; i < wr_count; ++i) {
+ if (copy_from_user(user_wr, buf + i * wqe_size,
+ wqe_size)) {
+ ret = -EFAULT;
+ goto err;
+ }
+
+ if (user_wr->num_sge + sg_ind > sge_count) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
+ user_wr->num_sge * sizeof (struct ib_sge),
+ GFP_KERNEL);
+ if (!next) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (!last)
+ wr = next;
+ else
+ last->next = next;
+ last = next;
+
+ next->next = NULL;
+ next->wr_id = user_wr->wr_id;
+ next->num_sge = user_wr->num_sge;
+
+ if (next->num_sge) {
+ next->sg_list = (void *) next +
+ ALIGN(sizeof *next, sizeof (struct ib_sge));
+ if (copy_from_user(next->sg_list,
+ buf + wr_count * wqe_size +
+ sg_ind * sizeof (struct ib_sge),
+ next->num_sge * sizeof (struct ib_sge))) {
+ ret = -EFAULT;
+ goto err;
+ }
+ sg_ind += next->num_sge;
+ } else
+ next->sg_list = NULL;
+ }
+
+ kfree(user_wr);
+ return wr;
+
+err:
+ kfree(user_wr);
+
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
+ return ERR_PTR(ret);
+}
+
ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_post_recv cmd;
struct ib_uverbs_post_recv_resp resp;
- struct ib_uverbs_recv_wr *m_wr, *j;
- struct ib_recv_wr *wr, *i, *bad_wr;
- struct ib_sge *s;
+ struct ib_recv_wr *wr, *next, *bad_wr;
struct ib_qp *qp;
- int size;
- int count;
ssize_t ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
+ in_len - sizeof cmd, cmd.wr_count,
+ cmd.sge_count, cmd.wqe_size);
+ if (IS_ERR(wr))
+ return PTR_ERR(wr);
+
down(&ib_uverbs_idr_mutex);
qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
if (!qp || qp->uobject->context != file->ucontext)
goto out;
- size = (cmd.wr_count * sizeof *m_wr) + (cmd.sge_count * sizeof *s);
- m_wr = kmalloc(size, GFP_KERNEL);
- if (!m_wr) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (copy_from_user(m_wr, (void __user *)cmd.wr, size)) {
- ret = -EFAULT;
- goto wrout;
- }
-
- wr = kmalloc(cmd.wr_count * sizeof *wr, GFP_KERNEL);
- if (!wr) {
- ret = -ENOMEM;
- goto wrout;
- }
-
- s = (struct ib_sge *)(m_wr + cmd.wr_count);
-
- i = wr;
- j = m_wr;
- count = 0;
- while (count++ < cmd.wr_count) {
- struct ib_recv_wr *t = i++;
- struct ib_uverbs_recv_wr *u = j++;
-
- if (count < cmd.wr_count)
- t->next = i;
- else
- t->next = NULL;
-
- t->wr_id = u->wr_id;
- t->num_sge = u->num_sge;
-
- if (t->num_sge) {
- t->sg_list = s;
- s += t->num_sge;
- } else
- t->sg_list = NULL;
- }
-
+ resp.bad_wr = 0;
ret = qp->device->post_recv(qp, wr, &bad_wr);
- resp.bad_wr = ret ? (bad_wr - wr) + 1 : 0;
+ if (ret)
+ for (next = wr; next; next = next->next) {
+ ++resp.bad_wr;
+ if (next == bad_wr)
+ break;
+ }
+
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp))
ret = -EFAULT;
- kfree(wr);
-
-wrout:
- kfree(m_wr);
-
out:
up(&ib_uverbs_idr_mutex);
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
return ret ? ret : in_len;
}
@@ -1294,81 +1373,50 @@ ssize_t ib_uverbs_post_srq_recv(struct i
const char __user *buf, int in_len,
int out_len)
{
- struct ib_uverbs_post_srq_recv cmd;
+ struct ib_uverbs_post_srq_recv cmd;
struct ib_uverbs_post_srq_recv_resp resp;
- struct ib_uverbs_recv_wr *m_wr, *j;
- struct ib_recv_wr *wr, *i, *bad_wr;
- struct ib_sge *s;
- struct ib_srq *srq;
- int size;
- int count;
- ssize_t ret = -EFAULT;
+ struct ib_recv_wr *wr, *next, *bad_wr;
+ struct ib_srq *srq;
+ ssize_t ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
+ in_len - sizeof cmd, cmd.wr_count,
+ cmd.sge_count, cmd.wqe_size);
+ if (IS_ERR(wr))
+ return PTR_ERR(wr);
+
down(&ib_uverbs_idr_mutex);
srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
if (!srq || srq->uobject->context != file->ucontext)
goto out;
- size = (cmd.wr_count * sizeof *m_wr) + (cmd.sge_count * sizeof *s);
- m_wr = kmalloc(size, GFP_KERNEL);
- if (!m_wr) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (copy_from_user(m_wr, (void __user *)cmd.wr, size)) {
- goto wrout;
- }
-
- wr = kmalloc(cmd.wr_count * sizeof *wr, GFP_KERNEL);
- if (!wr) {
- ret = -ENOMEM;
- goto wrout;
- }
-
- s = (struct ib_sge *)(m_wr + cmd.wr_count);
-
- i = wr;
- j = m_wr;
- count = 0;
- while (count++ < cmd.wr_count) {
- struct ib_recv_wr *t = i++;
- struct ib_uverbs_recv_wr *u = j++;
-
- if (count < cmd.wr_count)
- t->next = i;
- else
- t->next = NULL;
-
- t->wr_id = u->wr_id;
- t->num_sge = u->num_sge;
-
- if (t->num_sge) {
- t->sg_list = s;
- s += t->num_sge;
- } else
- t->sg_list = NULL;
- }
-
+ resp.bad_wr = 0;
ret = srq->device->post_srq_recv(srq, wr, &bad_wr);
- resp.bad_wr = ret ? (bad_wr - wr) + 1 : 0;
+ if (ret)
+ for (next = wr; next; next = next->next) {
+ ++resp.bad_wr;
+ if (next == bad_wr)
+ break;
+ }
+
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp))
ret = -EFAULT;
- kfree(wr);
-
-wrout:
- kfree(m_wr);
-
out:
up(&ib_uverbs_idr_mutex);
+ while (wr) {
+ next = wr->next;
+ kfree(wr);
+ wr = next;
+ }
+
return ret ? ret : in_len;
}
@@ -1405,19 +1453,16 @@ ssize_t ib_uverbs_create_ah(struct ib_uv
uobj->user_handle = cmd.user_handle;
uobj->context = file->ucontext;
- attr.dlid = cmd.attr.dlid;
- attr.sl = cmd.attr.sl;
- attr.src_path_bits = cmd.attr.src_path_bits;
- attr.static_rate = cmd.attr.static_rate;
- attr.port_num = cmd.attr.port_num;
- attr.grh.flow_label = cmd.attr.grh.flow_label;
- attr.grh.sgid_index = cmd.attr.grh.sgid_index;
- attr.grh.hop_limit = cmd.attr.grh.hop_limit;
+ attr.dlid = cmd.attr.dlid;
+ attr.sl = cmd.attr.sl;
+ attr.src_path_bits = cmd.attr.src_path_bits;
+ attr.static_rate = cmd.attr.static_rate;
+ attr.port_num = cmd.attr.port_num;
+ attr.grh.flow_label = cmd.attr.grh.flow_label;
+ attr.grh.sgid_index = cmd.attr.grh.sgid_index;
+ attr.grh.hop_limit = cmd.attr.grh.hop_limit;
attr.grh.traffic_class = cmd.attr.grh.traffic_class;
- attr.grh.dgid.global.subnet_prefix =
- cmd.attr.grh.dgid.global.subnet_prefix;
- attr.grh.dgid.global.interface_id =
- cmd.attr.grh.dgid.global.interface_id;
+ memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16);
ah = ib_create_ah(pd, &attr);
if (IS_ERR(ah)) {
Index: libibverbs/include/infiniband/kern-abi.h
===================================================================
--- libibverbs/include/infiniband/kern-abi.h (revision 3745)
+++ libibverbs/include/infiniband/kern-abi.h (working copy)
@@ -94,8 +94,11 @@ enum {
* Make sure that all structs defined in this file remain laid out so
* that they pack the same way on 32-bit and 64-bit architectures (to
* avoid incompatibility between 32-bit userspace and 64-bit kernels).
- * In particular do not use pointer types -- pass pointers in __u64
- * instead.
+ * Specifically:
+ * - Do not use pointer types -- pass pointers in __u64 instead.
+ * - Make sure that any structure larger than 4 bytes is padded to a
+ * multiple of 8 bytes. Otherwise the structure size will be
+ * different between 32-bit and 64-bit architectures.
*/
struct ibv_kern_async_event {
@@ -314,7 +317,7 @@ struct ibv_kern_wc {
__u8 sl;
__u8 dlid_path_bits;
__u8 port_num;
- __u8 reserved; /* Align struct to 8 bytes */
+ __u8 reserved;
};
struct ibv_poll_cq {
@@ -328,7 +331,7 @@ struct ibv_poll_cq {
struct ibv_poll_cq_resp {
__u32 count;
- __u32 reserved; /* Align struct to 8 bytes */
+ __u32 reserved;
struct ibv_kern_wc wc[];
};
@@ -452,20 +455,20 @@ struct ibv_kern_send_wr {
struct {
__u64 remote_addr;
__u32 rkey;
- __u32 reserved; /* Align struct to 8 bytes */
+ __u32 reserved;
} rdma;
struct {
__u64 remote_addr;
__u64 compare_add;
__u64 swap;
__u32 rkey;
- __u32 reserved; /* Align struct to 8 bytes */
+ __u32 reserved;
} atomic;
struct {
__u32 ah;
__u32 remote_qpn;
__u32 remote_qkey;
- __u32 reserved; /* Align struct to 8 bytes */
+ __u32 reserved;
} ud;
} wr;
};
@@ -478,8 +481,7 @@ struct ibv_post_send {
__u32 qp_handle;
__u32 wr_count;
__u32 sge_count;
- __u32 reserved; /* Align struct to 8 bytes */
- __u64 wr;
+ __u32 wqe_size;
};
struct ibv_post_send_resp {
@@ -489,7 +491,7 @@ struct ibv_post_send_resp {
struct ibv_kern_recv_wr {
__u64 wr_id;
__u32 num_sge;
- __u32 reserved; /* Align struct to 8 bytes */
+ __u32 reserved;
};
struct ibv_post_recv {
@@ -500,8 +502,7 @@ struct ibv_post_recv {
__u32 qp_handle;
__u32 wr_count;
__u32 sge_count;
- __u32 reserved; /* Align struct to 8 bytes */
- __u64 wr;
+ __u32 wqe_size;
};
struct ibv_post_recv_resp {
@@ -516,29 +517,20 @@ struct ibv_post_srq_recv {
__u32 srq_handle;
__u32 wr_count;
__u32 sge_count;
- __u32 reserved; /* Align struct to 8 bytes */
- __u64 wr;
+ __u32 wqe_size;
};
struct ibv_post_srq_recv_resp {
__u32 bad_wr;
};
-union ibv_kern_gid {
- __u8 raw[16];
- struct {
- __u64 subnet_prefix;
- __u64 interface_id;
- } global;
-};
-
struct ibv_kern_global_route {
- union ibv_kern_gid dgid;
+ __u8 dgid[16];
__u32 flow_label;
__u8 sgid_index;
__u8 hop_limit;
__u8 traffic_class;
- __u8 reserved; /* Align struct to 8 bytes */
+ __u8 reserved;
};
struct ibv_kern_ah_attr {
@@ -549,7 +541,7 @@ struct ibv_kern_ah_attr {
__u8 static_rate;
__u8 is_global;
__u8 port_num;
- __u8 reserved; /* Align struct to 8 bytes */
+ __u8 reserved;
};
struct ibv_create_ah {
@@ -559,7 +551,7 @@ struct ibv_create_ah {
__u64 response;
__u64 user_handle;
__u32 pd_handle;
- __u32 reserved; /* Align struct to 8 bytes */
+ __u32 reserved;
struct ibv_kern_ah_attr attr;
};
Index: libibverbs/src/cmd.c
===================================================================
--- libibverbs/src/cmd.c (revision 3745)
+++ libibverbs/src/cmd.c (working copy)
@@ -314,7 +314,7 @@ int ibv_cmd_poll_cq(struct ibv_cq *ibcq,
int ret;
rsize = sizeof *resp + ne * sizeof(struct ibv_kern_wc);
- resp = malloc(rsize);
+ resp = malloc(rsize);
if (!resp)
return -1;
@@ -327,19 +327,19 @@ int ibv_cmd_poll_cq(struct ibv_cq *ibcq,
goto out;
}
- for(i = 0; i < ne; i++) {
- wc[i].wr_id = resp->wc[i].wr_id;
- wc[i].status = resp->wc[i].status;
- wc[i].opcode = resp->wc[i].opcode;
- wc[i].vendor_err = resp->wc[i].vendor_err;
- wc[i].byte_len = resp->wc[i].byte_len;
- wc[i].imm_data = resp->wc[i].imm_data;
- wc[i].qp_num = resp->wc[i].qp_num;
- wc[i].src_qp = resp->wc[i].src_qp;
- wc[i].wc_flags = resp->wc[i].wc_flags;
- wc[i].pkey_index = resp->wc[i].pkey_index;
- wc[i].slid = resp->wc[i].slid;
- wc[i].sl = resp->wc[i].sl;
+ for (i = 0; i < resp->count; i++) {
+ wc[i].wr_id = resp->wc[i].wr_id;
+ wc[i].status = resp->wc[i].status;
+ wc[i].opcode = resp->wc[i].opcode;
+ wc[i].vendor_err = resp->wc[i].vendor_err;
+ wc[i].byte_len = resp->wc[i].byte_len;
+ wc[i].imm_data = resp->wc[i].imm_data;
+ wc[i].qp_num = resp->wc[i].qp_num;
+ wc[i].src_qp = resp->wc[i].src_qp;
+ wc[i].wc_flags = resp->wc[i].wc_flags;
+ wc[i].pkey_index = resp->wc[i].pkey_index;
+ wc[i].slid = resp->wc[i].slid;
+ wc[i].sl = resp->wc[i].sl;
wc[i].dlid_path_bits = resp->wc[i].dlid_path_bits;
}
@@ -582,42 +582,43 @@ static int ibv_cmd_destroy_qp_v1(struct
int ibv_cmd_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
struct ibv_send_wr **bad_wr)
{
- struct ibv_post_send cmd;
+ struct ibv_post_send *cmd;
struct ibv_post_send_resp resp;
struct ibv_send_wr *i;
struct ibv_kern_send_wr *n, *tmp;
struct ibv_sge *s;
unsigned wr_count = 0;
unsigned sge_count = 0;
- int ret;
+ int size;
+ int ret = 0;
- for(i = wr; i; i = i->next) {
+ for (i = wr; i; i = i->next) {
wr_count++;
sge_count += i->num_sge;
}
- n = malloc((wr_count * sizeof *n) + (sge_count * sizeof *s));
- if(!n)
- return errno;
+ size = sizeof *cmd + wr_count * sizeof *n + sge_count * sizeof *s;
+ cmd = alloca(size);
- IBV_INIT_CMD_RESP(&cmd, sizeof cmd, POST_SEND, &resp, sizeof resp);
- cmd.qp_handle = ibqp->handle;
- cmd.wr_count = wr_count;
- cmd.sge_count = sge_count;
- cmd.wr = (uintptr_t)n;
+ IBV_INIT_CMD_RESP(cmd, size, POST_SEND, &resp, sizeof resp);
+ cmd->qp_handle = ibqp->handle;
+ cmd->wr_count = wr_count;
+ cmd->sge_count = sge_count;
+ cmd->wqe_size = sizeof *n;
- s = (struct ibv_sge *)(n + wr_count);
+ n = (struct ibv_kern_send_wr *) ((void *) cmd + sizeof *cmd);
+ s = (struct ibv_sge *) (n + wr_count);
tmp = n;
- for(i = wr; i; i = i->next) {
- tmp->wr_id = i->wr_id;
- tmp->num_sge = i->num_sge;
- tmp->opcode = i->opcode;
+ for (i = wr; i; i = i->next) {
+ tmp->wr_id = i->wr_id;
+ tmp->num_sge = i->num_sge;
+ tmp->opcode = i->opcode;
tmp->send_flags = i->send_flags;
- tmp->imm_data = i->imm_data;
- if(ibqp->qp_type == IBV_QPT_UD) {
- tmp->wr.ud.ah = i->wr.ud.ah->handle;
- tmp->wr.ud.remote_qpn = i->wr.ud.remote_qpn;
+ tmp->imm_data = i->imm_data;
+ if (ibqp->qp_type == IBV_QPT_UD) {
+ tmp->wr.ud.ah = i->wr.ud.ah->handle;
+ tmp->wr.ud.remote_qpn = i->wr.ud.remote_qpn;
tmp->wr.ud.remote_qkey = i->wr.ud.remote_qkey;
} else {
switch(i->opcode) {
@@ -642,7 +643,7 @@ int ibv_cmd_post_send(struct ibv_qp *ibq
}
}
- if(tmp->num_sge) {
+ if (tmp->num_sge) {
memcpy(s, i->sg_list, tmp->num_sge * sizeof *s);
s += tmp->num_sge;
}
@@ -650,63 +651,57 @@ int ibv_cmd_post_send(struct ibv_qp *ibq
tmp++;
}
- if (write(ibqp->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) {
+ resp.bad_wr = 0;
+ if (write(ibqp->context->cmd_fd, cmd, size) != sizeof cmd)
ret = errno;
- goto out;
- }
- ret = 0;
-
-out:
wr_count = resp.bad_wr;
- if(wr_count) {
+ if (wr_count) {
i = wr;
- while(--wr_count)
+ while (--wr_count)
i = i->next;
*bad_wr = i;
}
- free(n);
return ret;
}
int ibv_cmd_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr)
{
- struct ibv_post_recv cmd;
+ struct ibv_post_recv *cmd;
struct ibv_post_recv_resp resp;
struct ibv_recv_wr *i;
struct ibv_kern_recv_wr *n, *tmp;
struct ibv_sge *s;
unsigned wr_count = 0;
unsigned sge_count = 0;
- int ret;
+ int size;
+ int ret = 0;
- for(i = wr; i; i = i->next) {
+ for (i = wr; i; i = i->next) {
wr_count++;
sge_count += i->num_sge;
}
- n = malloc((wr_count * sizeof *n) + (sge_count * sizeof *s));
- if(!n) {
- return errno;
- }
+ size = sizeof *cmd + wr_count * sizeof *n + sge_count * sizeof *s;
+ cmd = alloca(size);
- resp.bad_wr = 0;
- IBV_INIT_CMD_RESP(&cmd, sizeof cmd, POST_RECV, &resp, sizeof resp);
- cmd.qp_handle = ibqp->handle;
- cmd.wr_count = wr_count;
- cmd.sge_count = sge_count;
- cmd.wr = (uintptr_t)n;
+ IBV_INIT_CMD_RESP(cmd, size, POST_RECV, &resp, sizeof resp);
+ cmd->qp_handle = ibqp->handle;
+ cmd->wr_count = wr_count;
+ cmd->sge_count = sge_count;
+ cmd->wqe_size = sizeof *n;
- s = (struct ibv_sge *)(n + wr_count);
+ n = (struct ibv_kern_recv_wr *) ((void *) cmd + sizeof *cmd);
+ s = (struct ibv_sge *) (n + wr_count);
tmp = n;
- for(i = wr; i; i = i->next) {
- tmp->wr_id = i->wr_id;
+ for (i = wr; i; i = i->next) {
+ tmp->wr_id = i->wr_id;
tmp->num_sge = i->num_sge;
- if(tmp->num_sge) {
+ if (tmp->num_sge) {
memcpy(s, i->sg_list, tmp->num_sge * sizeof *s);
s += tmp->num_sge;
}
@@ -714,56 +709,50 @@ int ibv_cmd_post_recv(struct ibv_qp *ibq
tmp++;
}
- if (write(ibqp->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) {
+ resp.bad_wr = 0;
+ if (write(ibqp->context->cmd_fd, cmd, size) != sizeof cmd)
ret = errno;
- goto out;
- }
- ret = 0;
-
-out:
wr_count = resp.bad_wr;
- if(wr_count) {
+ if (wr_count) {
i = wr;
- while(--wr_count)
+ while (--wr_count)
i = i->next;
*bad_wr = i;
}
- free(n);
return ret;
}
int ibv_cmd_post_srq_recv(struct ibv_srq *srq, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr)
{
- struct ibv_post_srq_recv cmd;
+ struct ibv_post_srq_recv *cmd;
struct ibv_post_srq_recv_resp resp;
struct ibv_recv_wr *i;
struct ibv_kern_recv_wr *n, *tmp;
struct ibv_sge *s;
unsigned wr_count = 0;
unsigned sge_count = 0;
- int ret;
+ int size;
+ int ret = 0;
for (i = wr; i; i = i->next) {
wr_count++;
sge_count += i->num_sge;
}
- n = malloc((wr_count * sizeof *n) + (sge_count * sizeof *s));
- if (!n) {
- return errno;
- }
+ size = sizeof *cmd + wr_count * sizeof *n + sge_count * sizeof *s;
+ cmd = alloca(size);
- resp.bad_wr = 0;
- IBV_INIT_CMD_RESP(&cmd, sizeof cmd, POST_SRQ_RECV, &resp, sizeof resp);
- cmd.srq_handle = srq->handle;
- cmd.wr_count = wr_count;
- cmd.sge_count = sge_count;
- cmd.wr = (uintptr_t)n;
+ IBV_INIT_CMD_RESP(cmd, size, POST_SRQ_RECV, &resp, sizeof resp);
+ cmd->srq_handle = srq->handle;
+ cmd->wr_count = wr_count;
+ cmd->sge_count = sge_count;
+ cmd->wqe_size = sizeof *n;
- s = (struct ibv_sge *)(n + wr_count);
+ n = (struct ibv_kern_recv_wr *) ((void *) cmd + sizeof *cmd);
+ s = (struct ibv_sge *) (n + wr_count);
tmp = n;
for (i = wr; i; i = i->next) {
@@ -778,14 +767,10 @@ int ibv_cmd_post_srq_recv(struct ibv_srq
tmp++;
}
- if (write(srq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) {
+ resp.bad_wr = 0;
+ if (write(srq->context->cmd_fd, cmd, size) != sizeof cmd)
ret = errno;
- goto out;
- }
- ret = 0;
-
-out:
wr_count = resp.bad_wr;
if (wr_count) {
i = wr;
@@ -794,7 +779,6 @@ out:
*bad_wr = i;
}
- free(n);
return ret;
}
@@ -805,7 +789,7 @@ int ibv_cmd_create_ah(struct ibv_pd *pd,
struct ibv_create_ah_resp resp;
IBV_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_AH, &resp, sizeof resp);
- cmd.user_handle = (uintptr_t)ah;
+ cmd.user_handle = (uintptr_t) ah;
cmd.pd_handle = pd->handle;
cmd.attr.dlid = attr->dlid;
cmd.attr.sl = attr->sl;
@@ -817,8 +801,7 @@ int ibv_cmd_create_ah(struct ibv_pd *pd,
cmd.attr.grh.sgid_index = attr->grh.sgid_index;
cmd.attr.grh.hop_limit = attr->grh.hop_limit;
cmd.attr.grh.traffic_class = attr->grh.traffic_class;
- cmd.attr.grh.dgid.global.subnet_prefix = attr->grh.dgid.global.subnet_prefix;
- cmd.attr.grh.dgid.global.interface_id = attr->grh.dgid.global.interface_id;
+ memcpy(cmd.attr.grh.dgid, attr->grh.dgid.raw, 16);
if (write(pd->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd)
return errno;
Index: libipathoib/libipathoib.spec.in
===================================================================
--- libipathoib/libipathoib.spec.in (revision 3745)
+++ libipathoib/libipathoib.spec.in (working copy)
@@ -41,7 +41,7 @@ Summary: PathScale InfiniPath HCA Usersp
Name: libipathoib
Version: %ver
Release: %rel
-Copyright: Dual GPL/BSD
+License: GPL/BSD
Group: System Environment/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-root
Source: http://openib.org/downloads/%{name}-%{version}.tar.gz
@@ -51,6 +51,15 @@ Requires: libibverbs
%description
libipathoib provides a device-specific userspace driver for PathScale HCAs.
+%package devel
+Summary: Development files for the libipathoib driver
+Group: System Environment/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Static version of libipathoib that may be linked directly to an
+application, which may be useful for debugging.
+
%prep
%setup -q
@@ -59,14 +68,19 @@ libipathoib provides a device-specific u
make
%install
-make DESTDIR=${RPM_BUILD_ROOT} install
+rm -rf $RPM_BUILD_ROOT
+%makeinstall
# remove unpackaged files from the buildroot
-rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/infiniband/*.la
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
-%{_libdir}/libipathoib*.so.*
-%doc AUTHORS COPYING ChangeLog NEWS README
+%{_libdir}/infiniband/ipathoib.so
+%doc AUTHORS COPYING
+
+%files devel
+%defattr(-,root,root,-)
+%{_libdir}/infiniband/ipathoib.a
Index: libipathoib/src/ipathoib.c
===================================================================
--- libipathoib/src/ipathoib.c (revision 3745)
+++ libipathoib/src/ipathoib.c (working copy)
@@ -43,7 +43,6 @@
#include <unistd.h>
#include "ipathoib.h"
-#include "ipathoib-abi.h"
#ifndef PCI_VENDOR_ID_PATHSCALE
#define PCI_VENDOR_ID_PATHSCALE 0x1fc1
Index: libipathoib/src/verbs.c
===================================================================
--- libipathoib/src/verbs.c (revision 3745)
+++ libipathoib/src/verbs.c (working copy)
@@ -45,7 +45,6 @@
#include <netinet/in.h>
#include "ipathoib.h"
-#include "ipathoib-abi.h"
int ipath_query_device(struct ibv_context *context,
struct ibv_device_attr *attr)
Index: libipathoib/src/ipathoib-abi.h
===================================================================
--- libipathoib/src/ipathoib-abi.h (revision 3745)
+++ libipathoib/src/ipathoib-abi.h (working copy)
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2005. PathScale, Inc. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Patent licenses, if any, provided herein do not apply to
- * combinations of this program with other software, or any other
- * product whatsoever.
- */
-
-#ifndef IPATH_ABI_H
-#define IPATH_ABI_H
-
-#include <infiniband/kern-abi.h>
-
-struct ipath_alloc_ucontext {
- struct ibv_get_context ibv_cmd;
- __u64 respbuf;
-};
-
-struct ipath_alloc_ucontext_resp {
- __u32 uarc_size;
-};
-
-#endif /* IPATH_ABI_H */
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general
To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general