Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/mthca/mthca_srq.c
Show All 30 Lines | |||||
*/ | */ | ||||
#include <linux/slab.h> | #include <linux/slab.h> | ||||
#include <linux/string.h> | #include <linux/string.h> | ||||
#include <linux/sched.h> | #include <linux/sched.h> | ||||
#include <asm/io.h> | #include <asm/io.h> | ||||
#include <rdma/uverbs_ioctl.h> | |||||
#include "mthca_dev.h" | #include "mthca_dev.h" | ||||
#include "mthca_cmd.h" | #include "mthca_cmd.h" | ||||
#include "mthca_memfree.h" | #include "mthca_memfree.h" | ||||
#include "mthca_wqe.h" | #include "mthca_wqe.h" | ||||
enum { | enum { | ||||
MTHCA_MAX_DIRECT_SRQ_SIZE = 4 * PAGE_SIZE | MTHCA_MAX_DIRECT_SRQ_SIZE = 4 * PAGE_SIZE | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
static inline int *wqe_to_link(void *wqe) | static inline int *wqe_to_link(void *wqe) | ||||
{ | { | ||||
return (int *) (wqe + offsetof(struct mthca_next_seg, imm)); | return (int *) (wqe + offsetof(struct mthca_next_seg, imm)); | ||||
} | } | ||||
static void mthca_tavor_init_srq_context(struct mthca_dev *dev, | static void mthca_tavor_init_srq_context(struct mthca_dev *dev, | ||||
struct mthca_pd *pd, | struct mthca_pd *pd, | ||||
struct mthca_srq *srq, | struct mthca_srq *srq, | ||||
struct mthca_tavor_srq_context *context) | struct mthca_tavor_srq_context *context, | ||||
struct ib_udata *udata) | |||||
{ | { | ||||
struct mthca_ucontext *ucontext = rdma_udata_to_drv_context( | |||||
udata, struct mthca_ucontext, ibucontext); | |||||
memset(context, 0, sizeof *context); | memset(context, 0, sizeof *context); | ||||
context->wqe_base_ds = cpu_to_be64(1 << (srq->wqe_shift - 4)); | context->wqe_base_ds = cpu_to_be64(1 << (srq->wqe_shift - 4)); | ||||
context->state_pd = cpu_to_be32(pd->pd_num); | context->state_pd = cpu_to_be32(pd->pd_num); | ||||
context->lkey = cpu_to_be32(srq->mr.ibmr.lkey); | context->lkey = cpu_to_be32(srq->mr.ibmr.lkey); | ||||
if (pd->ibpd.uobject) | if (udata) | ||||
context->uar = | context->uar = cpu_to_be32(ucontext->uar.index); | ||||
cpu_to_be32(to_mucontext(pd->ibpd.uobject->context)->uar.index); | |||||
else | else | ||||
context->uar = cpu_to_be32(dev->driver_uar.index); | context->uar = cpu_to_be32(dev->driver_uar.index); | ||||
} | } | ||||
static void mthca_arbel_init_srq_context(struct mthca_dev *dev, | static void mthca_arbel_init_srq_context(struct mthca_dev *dev, | ||||
struct mthca_pd *pd, | struct mthca_pd *pd, | ||||
struct mthca_srq *srq, | struct mthca_srq *srq, | ||||
struct mthca_arbel_srq_context *context) | struct mthca_arbel_srq_context *context, | ||||
struct ib_udata *udata) | |||||
{ | { | ||||
struct mthca_ucontext *ucontext = rdma_udata_to_drv_context( | |||||
udata, struct mthca_ucontext, ibucontext); | |||||
int logsize; | int logsize; | ||||
memset(context, 0, sizeof *context); | memset(context, 0, sizeof *context); | ||||
logsize = ilog2(srq->max); | logsize = ilog2(srq->max); | ||||
context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn); | context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn); | ||||
context->lkey = cpu_to_be32(srq->mr.ibmr.lkey); | context->lkey = cpu_to_be32(srq->mr.ibmr.lkey); | ||||
context->db_index = cpu_to_be32(srq->db_index); | context->db_index = cpu_to_be32(srq->db_index); | ||||
context->logstride_usrpage = cpu_to_be32((srq->wqe_shift - 4) << 29); | context->logstride_usrpage = cpu_to_be32((srq->wqe_shift - 4) << 29); | ||||
if (pd->ibpd.uobject) | if (udata) | ||||
context->logstride_usrpage |= | context->logstride_usrpage |= cpu_to_be32(ucontext->uar.index); | ||||
cpu_to_be32(to_mucontext(pd->ibpd.uobject->context)->uar.index); | |||||
else | else | ||||
context->logstride_usrpage |= cpu_to_be32(dev->driver_uar.index); | context->logstride_usrpage |= cpu_to_be32(dev->driver_uar.index); | ||||
context->eq_pd = cpu_to_be32(MTHCA_EQ_ASYNC << 24 | pd->pd_num); | context->eq_pd = cpu_to_be32(MTHCA_EQ_ASYNC << 24 | pd->pd_num); | ||||
} | } | ||||
static void mthca_free_srq_buf(struct mthca_dev *dev, struct mthca_srq *srq) | static void mthca_free_srq_buf(struct mthca_dev *dev, struct mthca_srq *srq) | ||||
{ | { | ||||
mthca_buf_free(dev, srq->max << srq->wqe_shift, &srq->queue, | mthca_buf_free(dev, srq->max << srq->wqe_shift, &srq->queue, | ||||
srq->is_direct, &srq->mr); | srq->is_direct, &srq->mr); | ||||
kfree(srq->wrid); | kfree(srq->wrid); | ||||
} | } | ||||
static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd, | static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd, | ||||
struct mthca_srq *srq) | struct mthca_srq *srq, struct ib_udata *udata) | ||||
{ | { | ||||
struct mthca_data_seg *scatter; | struct mthca_data_seg *scatter; | ||||
void *wqe; | void *wqe; | ||||
int err; | int err; | ||||
int i; | int i; | ||||
if (pd->ibpd.uobject) | if (udata) | ||||
return 0; | return 0; | ||||
srq->wrid = kmalloc(srq->max * sizeof (u64), GFP_KERNEL); | srq->wrid = kmalloc(srq->max * sizeof (u64), GFP_KERNEL); | ||||
if (!srq->wrid) | if (!srq->wrid) | ||||
return -ENOMEM; | return -ENOMEM; | ||||
err = mthca_buf_alloc(dev, srq->max << srq->wqe_shift, | err = mthca_buf_alloc(dev, srq->max << srq->wqe_shift, | ||||
MTHCA_MAX_DIRECT_SRQ_SIZE, | MTHCA_MAX_DIRECT_SRQ_SIZE, | ||||
Show All 28 Lines | static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd, | ||||
} | } | ||||
srq->last = get_wqe(srq, srq->max - 1); | srq->last = get_wqe(srq, srq->max - 1); | ||||
return 0; | return 0; | ||||
} | } | ||||
int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | ||||
struct ib_srq_attr *attr, struct mthca_srq *srq) | struct ib_srq_attr *attr, struct mthca_srq *srq, | ||||
struct ib_udata *udata) | |||||
{ | { | ||||
struct mthca_mailbox *mailbox; | struct mthca_mailbox *mailbox; | ||||
int ds; | int ds; | ||||
int err; | int err; | ||||
/* Sanity check SRQ size before proceeding */ | /* Sanity check SRQ size before proceeding */ | ||||
if (attr->max_wr > dev->limits.max_srq_wqes || | if (attr->max_wr > dev->limits.max_srq_wqes || | ||||
attr->max_sge > dev->limits.max_srq_sge) | attr->max_sge > dev->limits.max_srq_sge) | ||||
Show All 21 Lines | int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | ||||
if (srq->srqn == -1) | if (srq->srqn == -1) | ||||
return -ENOMEM; | return -ENOMEM; | ||||
if (mthca_is_memfree(dev)) { | if (mthca_is_memfree(dev)) { | ||||
err = mthca_table_get(dev, dev->srq_table.table, srq->srqn); | err = mthca_table_get(dev, dev->srq_table.table, srq->srqn); | ||||
if (err) | if (err) | ||||
goto err_out; | goto err_out; | ||||
if (!pd->ibpd.uobject) { | if (!udata) { | ||||
srq->db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SRQ, | srq->db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SRQ, | ||||
srq->srqn, &srq->db); | srq->srqn, &srq->db); | ||||
if (srq->db_index < 0) { | if (srq->db_index < 0) { | ||||
err = -ENOMEM; | err = -ENOMEM; | ||||
goto err_out_icm; | goto err_out_icm; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | ||||
if (IS_ERR(mailbox)) { | if (IS_ERR(mailbox)) { | ||||
err = PTR_ERR(mailbox); | err = PTR_ERR(mailbox); | ||||
goto err_out_db; | goto err_out_db; | ||||
} | } | ||||
err = mthca_alloc_srq_buf(dev, pd, srq); | err = mthca_alloc_srq_buf(dev, pd, srq, udata); | ||||
if (err) | if (err) | ||||
goto err_out_mailbox; | goto err_out_mailbox; | ||||
spin_lock_init(&srq->lock); | spin_lock_init(&srq->lock); | ||||
srq->refcount = 1; | srq->refcount = 1; | ||||
init_waitqueue_head(&srq->wait); | init_waitqueue_head(&srq->wait); | ||||
mutex_init(&srq->mutex); | mutex_init(&srq->mutex); | ||||
if (mthca_is_memfree(dev)) | if (mthca_is_memfree(dev)) | ||||
mthca_arbel_init_srq_context(dev, pd, srq, mailbox->buf); | mthca_arbel_init_srq_context(dev, pd, srq, mailbox->buf, udata); | ||||
else | else | ||||
mthca_tavor_init_srq_context(dev, pd, srq, mailbox->buf); | mthca_tavor_init_srq_context(dev, pd, srq, mailbox->buf, udata); | ||||
err = mthca_SW2HW_SRQ(dev, mailbox, srq->srqn); | err = mthca_SW2HW_SRQ(dev, mailbox, srq->srqn); | ||||
if (err) { | if (err) { | ||||
mthca_warn(dev, "SW2HW_SRQ failed (%d)\n", err); | mthca_warn(dev, "SW2HW_SRQ failed (%d)\n", err); | ||||
goto err_out_free_buf; | goto err_out_free_buf; | ||||
} | } | ||||
Show All 17 Lines | int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | ||||
return 0; | return 0; | ||||
err_out_free_srq: | err_out_free_srq: | ||||
err = mthca_HW2SW_SRQ(dev, mailbox, srq->srqn); | err = mthca_HW2SW_SRQ(dev, mailbox, srq->srqn); | ||||
if (err) | if (err) | ||||
mthca_warn(dev, "HW2SW_SRQ failed (%d)\n", err); | mthca_warn(dev, "HW2SW_SRQ failed (%d)\n", err); | ||||
err_out_free_buf: | err_out_free_buf: | ||||
if (!pd->ibpd.uobject) | if (!udata) | ||||
mthca_free_srq_buf(dev, srq); | mthca_free_srq_buf(dev, srq); | ||||
err_out_mailbox: | err_out_mailbox: | ||||
mthca_free_mailbox(dev, mailbox); | mthca_free_mailbox(dev, mailbox); | ||||
err_out_db: | err_out_db: | ||||
if (!pd->ibpd.uobject && mthca_is_memfree(dev)) | if (!udata && mthca_is_memfree(dev)) | ||||
mthca_free_db(dev, MTHCA_DB_TYPE_SRQ, srq->db_index); | mthca_free_db(dev, MTHCA_DB_TYPE_SRQ, srq->db_index); | ||||
err_out_icm: | err_out_icm: | ||||
mthca_table_put(dev, dev->srq_table.table, srq->srqn); | mthca_table_put(dev, dev->srq_table.table, srq->srqn); | ||||
err_out: | err_out: | ||||
mthca_free(&dev->srq_table.alloc, srq->srqn); | mthca_free(&dev->srq_table.alloc, srq->srqn); | ||||
▲ Show 20 Lines • Show All 381 Lines • Show Last 20 Lines |