Merge branches 'core', 'cxgb3', 'cxgb4', 'iser', 'iwpm', 'misc', 'mlx4', 'mlx5', 'noio', 'ocrdma', 'qib', 'srp' and 'usnic' into for-next
This commit is contained in:

5
drivers/infiniband/ulp/Makefile
Normal file
5
drivers/infiniband/ulp/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
obj-$(CONFIG_INFINIBAND_IPOIB) += ipoib/
|
||||
obj-$(CONFIG_INFINIBAND_SRP) += srp/
|
||||
obj-$(CONFIG_INFINIBAND_SRPT) += srpt/
|
||||
obj-$(CONFIG_INFINIBAND_ISER) += iser/
|
||||
obj-$(CONFIG_INFINIBAND_ISERT) += isert/
|
@@ -1030,10 +1030,20 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
|
||||
.cap.max_send_sge = 1,
|
||||
.sq_sig_type = IB_SIGNAL_ALL_WR,
|
||||
.qp_type = IB_QPT_RC,
|
||||
.qp_context = tx
|
||||
.qp_context = tx,
|
||||
.create_flags = IB_QP_CREATE_USE_GFP_NOIO
|
||||
};
|
||||
|
||||
return ib_create_qp(priv->pd, &attr);
|
||||
struct ib_qp *tx_qp;
|
||||
|
||||
tx_qp = ib_create_qp(priv->pd, &attr);
|
||||
if (PTR_ERR(tx_qp) == -EINVAL) {
|
||||
ipoib_warn(priv, "can't use GFP_NOIO for QPs on device %s, using GFP_KERNEL\n",
|
||||
priv->ca->name);
|
||||
attr.create_flags &= ~IB_QP_CREATE_USE_GFP_NOIO;
|
||||
tx_qp = ib_create_qp(priv->pd, &attr);
|
||||
}
|
||||
return tx_qp;
|
||||
}
|
||||
|
||||
static int ipoib_cm_send_req(struct net_device *dev,
|
||||
@@ -1104,12 +1114,14 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
|
||||
struct ipoib_dev_priv *priv = netdev_priv(p->dev);
|
||||
int ret;
|
||||
|
||||
p->tx_ring = vzalloc(ipoib_sendq_size * sizeof *p->tx_ring);
|
||||
p->tx_ring = __vmalloc(ipoib_sendq_size * sizeof *p->tx_ring,
|
||||
GFP_NOIO, PAGE_KERNEL);
|
||||
if (!p->tx_ring) {
|
||||
ipoib_warn(priv, "failed to allocate tx ring\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_tx;
|
||||
}
|
||||
memset(p->tx_ring, 0, ipoib_sendq_size * sizeof *p->tx_ring);
|
||||
|
||||
p->qp = ipoib_cm_create_tx_qp(p->dev, p);
|
||||
if (IS_ERR(p->qp)) {
|
||||
|
@@ -99,6 +99,7 @@ MODULE_PARM_DESC(pi_enable, "Enable T10-PI offload support (default:disabled)");
|
||||
module_param_named(pi_guard, iser_pi_guard, int, 0644);
|
||||
MODULE_PARM_DESC(pi_guard, "T10-PI guard_type, 0:CRC|1:IP_CSUM (default:CRC)");
|
||||
|
||||
static struct workqueue_struct *release_wq;
|
||||
struct iser_global ig;
|
||||
|
||||
void
|
||||
@@ -337,24 +338,6 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
|
||||
return cls_conn;
|
||||
}
|
||||
|
||||
static void
|
||||
iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
struct iser_conn *ib_conn = conn->dd_data;
|
||||
|
||||
iscsi_conn_teardown(cls_conn);
|
||||
/*
|
||||
* Userspace will normally call the stop callback and
|
||||
* already have freed the ib_conn, but if it goofed up then
|
||||
* we free it here.
|
||||
*/
|
||||
if (ib_conn) {
|
||||
ib_conn->iscsi_conn = NULL;
|
||||
iser_conn_put(ib_conn, 1); /* deref iscsi/ib conn unbinding */
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
|
||||
struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
|
||||
@@ -392,29 +375,39 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
|
||||
conn->dd_data = ib_conn;
|
||||
ib_conn->iscsi_conn = conn;
|
||||
|
||||
iser_conn_get(ib_conn); /* ref iscsi/ib conn binding */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)
|
||||
{
|
||||
struct iscsi_conn *iscsi_conn;
|
||||
struct iser_conn *ib_conn;
|
||||
|
||||
iscsi_conn = cls_conn->dd_data;
|
||||
ib_conn = iscsi_conn->dd_data;
|
||||
reinit_completion(&ib_conn->stop_completion);
|
||||
|
||||
return iscsi_conn_start(cls_conn);
|
||||
}
|
||||
|
||||
static void
|
||||
iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
|
||||
{
|
||||
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||
struct iser_conn *ib_conn = conn->dd_data;
|
||||
|
||||
iser_dbg("stopping iscsi_conn: %p, ib_conn: %p\n", conn, ib_conn);
|
||||
iscsi_conn_stop(cls_conn, flag);
|
||||
|
||||
/*
|
||||
* Userspace may have goofed up and not bound the connection or
|
||||
* might have only partially setup the connection.
|
||||
*/
|
||||
if (ib_conn) {
|
||||
iscsi_conn_stop(cls_conn, flag);
|
||||
/*
|
||||
* There is no unbind event so the stop callback
|
||||
* must release the ref from the bind.
|
||||
*/
|
||||
iser_conn_put(ib_conn, 1); /* deref iscsi/ib conn unbinding */
|
||||
conn->dd_data = NULL;
|
||||
complete(&ib_conn->stop_completion);
|
||||
}
|
||||
conn->dd_data = NULL;
|
||||
}
|
||||
|
||||
static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
|
||||
@@ -515,28 +508,28 @@ iscsi_iser_set_param(struct iscsi_cls_conn *cls_conn,
|
||||
case ISCSI_PARAM_HDRDGST_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
iser_err("DataDigest wasn't negotiated to None");
|
||||
iser_err("DataDigest wasn't negotiated to None\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
case ISCSI_PARAM_DATADGST_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
iser_err("DataDigest wasn't negotiated to None");
|
||||
iser_err("DataDigest wasn't negotiated to None\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
case ISCSI_PARAM_IFMARKER_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
iser_err("IFMarker wasn't negotiated to No");
|
||||
iser_err("IFMarker wasn't negotiated to No\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
case ISCSI_PARAM_OFMARKER_EN:
|
||||
sscanf(buf, "%d", &value);
|
||||
if (value) {
|
||||
iser_err("OFMarker wasn't negotiated to No");
|
||||
iser_err("OFMarker wasn't negotiated to No\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
break;
|
||||
@@ -652,19 +645,20 @@ iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
|
||||
struct iser_conn *ib_conn;
|
||||
|
||||
ib_conn = ep->dd_data;
|
||||
if (ib_conn->iscsi_conn)
|
||||
/*
|
||||
* Must suspend xmit path if the ep is bound to the
|
||||
* iscsi_conn, so we know we are not accessing the ib_conn
|
||||
* when we free it.
|
||||
*
|
||||
* This may not be bound if the ep poll failed.
|
||||
*/
|
||||
iscsi_suspend_tx(ib_conn->iscsi_conn);
|
||||
|
||||
|
||||
iser_info("ib conn %p state %d\n", ib_conn, ib_conn->state);
|
||||
iser_info("ep %p ib conn %p state %d\n", ep, ib_conn, ib_conn->state);
|
||||
iser_conn_terminate(ib_conn);
|
||||
|
||||
/*
|
||||
* if iser_conn and iscsi_conn are bound, we must wait iscsi_conn_stop
|
||||
* call and ISER_CONN_DOWN state before freeing the iser resources.
|
||||
* otherwise we are safe to free resources immediately.
|
||||
*/
|
||||
if (ib_conn->iscsi_conn) {
|
||||
INIT_WORK(&ib_conn->release_work, iser_release_work);
|
||||
queue_work(release_wq, &ib_conn->release_work);
|
||||
} else {
|
||||
iser_conn_release(ib_conn);
|
||||
}
|
||||
}
|
||||
|
||||
static umode_t iser_attr_is_visible(int param_type, int param)
|
||||
@@ -748,13 +742,13 @@ static struct iscsi_transport iscsi_iser_transport = {
|
||||
/* connection management */
|
||||
.create_conn = iscsi_iser_conn_create,
|
||||
.bind_conn = iscsi_iser_conn_bind,
|
||||
.destroy_conn = iscsi_iser_conn_destroy,
|
||||
.destroy_conn = iscsi_conn_teardown,
|
||||
.attr_is_visible = iser_attr_is_visible,
|
||||
.set_param = iscsi_iser_set_param,
|
||||
.get_conn_param = iscsi_conn_get_param,
|
||||
.get_ep_param = iscsi_iser_get_ep_param,
|
||||
.get_session_param = iscsi_session_get_param,
|
||||
.start_conn = iscsi_conn_start,
|
||||
.start_conn = iscsi_iser_conn_start,
|
||||
.stop_conn = iscsi_iser_conn_stop,
|
||||
/* iscsi host params */
|
||||
.get_host_param = iscsi_host_get_param,
|
||||
@@ -801,6 +795,12 @@ static int __init iser_init(void)
|
||||
mutex_init(&ig.connlist_mutex);
|
||||
INIT_LIST_HEAD(&ig.connlist);
|
||||
|
||||
release_wq = alloc_workqueue("release workqueue", 0, 0);
|
||||
if (!release_wq) {
|
||||
iser_err("failed to allocate release workqueue\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
iscsi_iser_scsi_transport = iscsi_register_transport(
|
||||
&iscsi_iser_transport);
|
||||
if (!iscsi_iser_scsi_transport) {
|
||||
@@ -819,7 +819,24 @@ register_transport_failure:
|
||||
|
||||
static void __exit iser_exit(void)
|
||||
{
|
||||
struct iser_conn *ib_conn, *n;
|
||||
int connlist_empty;
|
||||
|
||||
iser_dbg("Removing iSER datamover...\n");
|
||||
destroy_workqueue(release_wq);
|
||||
|
||||
mutex_lock(&ig.connlist_mutex);
|
||||
connlist_empty = list_empty(&ig.connlist);
|
||||
mutex_unlock(&ig.connlist_mutex);
|
||||
|
||||
if (!connlist_empty) {
|
||||
iser_err("Error cleanup stage completed but we still have iser "
|
||||
"connections, destroying them anyway.\n");
|
||||
list_for_each_entry_safe(ib_conn, n, &ig.connlist, conn_list) {
|
||||
iser_conn_release(ib_conn);
|
||||
}
|
||||
}
|
||||
|
||||
iscsi_unregister_transport(&iscsi_iser_transport);
|
||||
kmem_cache_destroy(ig.desc_cache);
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@
|
||||
|
||||
#define DRV_NAME "iser"
|
||||
#define PFX DRV_NAME ": "
|
||||
#define DRV_VER "1.3"
|
||||
#define DRV_VER "1.4"
|
||||
|
||||
#define iser_dbg(fmt, arg...) \
|
||||
do { \
|
||||
@@ -333,6 +333,8 @@ struct iser_conn {
|
||||
int post_recv_buf_count; /* posted rx count */
|
||||
atomic_t post_send_buf_count; /* posted tx count */
|
||||
char name[ISER_OBJECT_NAME_SIZE];
|
||||
struct work_struct release_work;
|
||||
struct completion stop_completion;
|
||||
struct list_head conn_list; /* entry in ig conn list */
|
||||
|
||||
char *login_buf;
|
||||
@@ -417,12 +419,12 @@ void iscsi_iser_recv(struct iscsi_conn *conn,
|
||||
|
||||
void iser_conn_init(struct iser_conn *ib_conn);
|
||||
|
||||
void iser_conn_get(struct iser_conn *ib_conn);
|
||||
|
||||
int iser_conn_put(struct iser_conn *ib_conn, int destroy_cma_id_allowed);
|
||||
void iser_conn_release(struct iser_conn *ib_conn);
|
||||
|
||||
void iser_conn_terminate(struct iser_conn *ib_conn);
|
||||
|
||||
void iser_release_work(struct work_struct *work);
|
||||
|
||||
void iser_rcv_completion(struct iser_rx_desc *desc,
|
||||
unsigned long dto_xfer_len,
|
||||
struct iser_conn *ib_conn);
|
||||
|
@@ -581,14 +581,30 @@ static int iser_conn_state_comp_exch(struct iser_conn *ib_conn,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iser_release_work(struct work_struct *work)
|
||||
{
|
||||
struct iser_conn *ib_conn;
|
||||
|
||||
ib_conn = container_of(work, struct iser_conn, release_work);
|
||||
|
||||
/* wait for .conn_stop callback */
|
||||
wait_for_completion(&ib_conn->stop_completion);
|
||||
|
||||
/* wait for the qp`s post send and post receive buffers to empty */
|
||||
wait_event_interruptible(ib_conn->wait,
|
||||
ib_conn->state == ISER_CONN_DOWN);
|
||||
|
||||
iser_conn_release(ib_conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all conn objects and deallocs conn descriptor
|
||||
*/
|
||||
static void iser_conn_release(struct iser_conn *ib_conn, int can_destroy_id)
|
||||
void iser_conn_release(struct iser_conn *ib_conn)
|
||||
{
|
||||
struct iser_device *device = ib_conn->device;
|
||||
|
||||
BUG_ON(ib_conn->state != ISER_CONN_DOWN);
|
||||
BUG_ON(ib_conn->state == ISER_CONN_UP);
|
||||
|
||||
mutex_lock(&ig.connlist_mutex);
|
||||
list_del(&ib_conn->conn_list);
|
||||
@@ -600,27 +616,13 @@ static void iser_conn_release(struct iser_conn *ib_conn, int can_destroy_id)
|
||||
if (device != NULL)
|
||||
iser_device_try_release(device);
|
||||
/* if cma handler context, the caller actually destroy the id */
|
||||
if (ib_conn->cma_id != NULL && can_destroy_id) {
|
||||
if (ib_conn->cma_id != NULL) {
|
||||
rdma_destroy_id(ib_conn->cma_id);
|
||||
ib_conn->cma_id = NULL;
|
||||
}
|
||||
iscsi_destroy_endpoint(ib_conn->ep);
|
||||
}
|
||||
|
||||
void iser_conn_get(struct iser_conn *ib_conn)
|
||||
{
|
||||
atomic_inc(&ib_conn->refcount);
|
||||
}
|
||||
|
||||
int iser_conn_put(struct iser_conn *ib_conn, int can_destroy_id)
|
||||
{
|
||||
if (atomic_dec_and_test(&ib_conn->refcount)) {
|
||||
iser_conn_release(ib_conn, can_destroy_id);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* triggers start of the disconnect procedures and wait for them to be done
|
||||
*/
|
||||
@@ -638,24 +640,19 @@ void iser_conn_terminate(struct iser_conn *ib_conn)
|
||||
if (err)
|
||||
iser_err("Failed to disconnect, conn: 0x%p err %d\n",
|
||||
ib_conn,err);
|
||||
|
||||
wait_event_interruptible(ib_conn->wait,
|
||||
ib_conn->state == ISER_CONN_DOWN);
|
||||
|
||||
iser_conn_put(ib_conn, 1); /* deref ib conn deallocate */
|
||||
}
|
||||
|
||||
static int iser_connect_error(struct rdma_cm_id *cma_id)
|
||||
static void iser_connect_error(struct rdma_cm_id *cma_id)
|
||||
{
|
||||
struct iser_conn *ib_conn;
|
||||
|
||||
ib_conn = (struct iser_conn *)cma_id->context;
|
||||
|
||||
ib_conn->state = ISER_CONN_DOWN;
|
||||
wake_up_interruptible(&ib_conn->wait);
|
||||
return iser_conn_put(ib_conn, 0); /* deref ib conn's cma id */
|
||||
}
|
||||
|
||||
static int iser_addr_handler(struct rdma_cm_id *cma_id)
|
||||
static void iser_addr_handler(struct rdma_cm_id *cma_id)
|
||||
{
|
||||
struct iser_device *device;
|
||||
struct iser_conn *ib_conn;
|
||||
@@ -664,7 +661,8 @@ static int iser_addr_handler(struct rdma_cm_id *cma_id)
|
||||
device = iser_device_find_by_ib_device(cma_id);
|
||||
if (!device) {
|
||||
iser_err("device lookup/creation failed\n");
|
||||
return iser_connect_error(cma_id);
|
||||
iser_connect_error(cma_id);
|
||||
return;
|
||||
}
|
||||
|
||||
ib_conn = (struct iser_conn *)cma_id->context;
|
||||
@@ -686,13 +684,12 @@ static int iser_addr_handler(struct rdma_cm_id *cma_id)
|
||||
ret = rdma_resolve_route(cma_id, 1000);
|
||||
if (ret) {
|
||||
iser_err("resolve route failed: %d\n", ret);
|
||||
return iser_connect_error(cma_id);
|
||||
iser_connect_error(cma_id);
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iser_route_handler(struct rdma_cm_id *cma_id)
|
||||
static void iser_route_handler(struct rdma_cm_id *cma_id)
|
||||
{
|
||||
struct rdma_conn_param conn_param;
|
||||
int ret;
|
||||
@@ -720,9 +717,9 @@ static int iser_route_handler(struct rdma_cm_id *cma_id)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return;
|
||||
failure:
|
||||
return iser_connect_error(cma_id);
|
||||
iser_connect_error(cma_id);
|
||||
}
|
||||
|
||||
static void iser_connected_handler(struct rdma_cm_id *cma_id)
|
||||
@@ -735,14 +732,13 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id)
|
||||
iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num);
|
||||
|
||||
ib_conn = (struct iser_conn *)cma_id->context;
|
||||
ib_conn->state = ISER_CONN_UP;
|
||||
wake_up_interruptible(&ib_conn->wait);
|
||||
if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_PENDING, ISER_CONN_UP))
|
||||
wake_up_interruptible(&ib_conn->wait);
|
||||
}
|
||||
|
||||
static int iser_disconnected_handler(struct rdma_cm_id *cma_id)
|
||||
static void iser_disconnected_handler(struct rdma_cm_id *cma_id)
|
||||
{
|
||||
struct iser_conn *ib_conn;
|
||||
int ret;
|
||||
|
||||
ib_conn = (struct iser_conn *)cma_id->context;
|
||||
|
||||
@@ -762,24 +758,19 @@ static int iser_disconnected_handler(struct rdma_cm_id *cma_id)
|
||||
ib_conn->state = ISER_CONN_DOWN;
|
||||
wake_up_interruptible(&ib_conn->wait);
|
||||
}
|
||||
|
||||
ret = iser_conn_put(ib_conn, 0); /* deref ib conn's cma id */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
iser_info("event %d status %d conn %p id %p\n",
|
||||
event->event, event->status, cma_id->context, cma_id);
|
||||
|
||||
switch (event->event) {
|
||||
case RDMA_CM_EVENT_ADDR_RESOLVED:
|
||||
ret = iser_addr_handler(cma_id);
|
||||
iser_addr_handler(cma_id);
|
||||
break;
|
||||
case RDMA_CM_EVENT_ROUTE_RESOLVED:
|
||||
ret = iser_route_handler(cma_id);
|
||||
iser_route_handler(cma_id);
|
||||
break;
|
||||
case RDMA_CM_EVENT_ESTABLISHED:
|
||||
iser_connected_handler(cma_id);
|
||||
@@ -789,18 +780,18 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
|
||||
case RDMA_CM_EVENT_CONNECT_ERROR:
|
||||
case RDMA_CM_EVENT_UNREACHABLE:
|
||||
case RDMA_CM_EVENT_REJECTED:
|
||||
ret = iser_connect_error(cma_id);
|
||||
iser_connect_error(cma_id);
|
||||
break;
|
||||
case RDMA_CM_EVENT_DISCONNECTED:
|
||||
case RDMA_CM_EVENT_DEVICE_REMOVAL:
|
||||
case RDMA_CM_EVENT_ADDR_CHANGE:
|
||||
ret = iser_disconnected_handler(cma_id);
|
||||
iser_disconnected_handler(cma_id);
|
||||
break;
|
||||
default:
|
||||
iser_err("Unexpected RDMA CM event (%d)\n", event->event);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iser_conn_init(struct iser_conn *ib_conn)
|
||||
@@ -809,7 +800,7 @@ void iser_conn_init(struct iser_conn *ib_conn)
|
||||
init_waitqueue_head(&ib_conn->wait);
|
||||
ib_conn->post_recv_buf_count = 0;
|
||||
atomic_set(&ib_conn->post_send_buf_count, 0);
|
||||
atomic_set(&ib_conn->refcount, 1); /* ref ib conn allocation */
|
||||
init_completion(&ib_conn->stop_completion);
|
||||
INIT_LIST_HEAD(&ib_conn->conn_list);
|
||||
spin_lock_init(&ib_conn->lock);
|
||||
}
|
||||
@@ -837,7 +828,6 @@ int iser_connect(struct iser_conn *ib_conn,
|
||||
|
||||
ib_conn->state = ISER_CONN_PENDING;
|
||||
|
||||
iser_conn_get(ib_conn); /* ref ib conn's cma id */
|
||||
ib_conn->cma_id = rdma_create_id(iser_cma_handler,
|
||||
(void *)ib_conn,
|
||||
RDMA_PS_TCP, IB_QPT_RC);
|
||||
@@ -874,9 +864,8 @@ id_failure:
|
||||
ib_conn->cma_id = NULL;
|
||||
addr_failure:
|
||||
ib_conn->state = ISER_CONN_DOWN;
|
||||
iser_conn_put(ib_conn, 1); /* deref ib conn's cma id */
|
||||
connect_failure:
|
||||
iser_conn_put(ib_conn, 1); /* deref ib conn deallocate */
|
||||
iser_conn_release(ib_conn);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -66,13 +66,10 @@ enum {
|
||||
SRP_TAG_NO_REQ = ~0U,
|
||||
SRP_TAG_TSK_MGMT = 1U << 31,
|
||||
|
||||
SRP_FMR_SIZE = 512,
|
||||
SRP_FMR_MIN_SIZE = 128,
|
||||
SRP_FMR_POOL_SIZE = 1024,
|
||||
SRP_FMR_DIRTY_SIZE = SRP_FMR_POOL_SIZE / 4,
|
||||
SRP_MAX_PAGES_PER_MR = 512,
|
||||
|
||||
SRP_MAP_ALLOW_FMR = 0,
|
||||
SRP_MAP_NO_FMR = 1,
|
||||
LOCAL_INV_WR_ID_MASK = 1,
|
||||
FAST_REG_WR_ID_MASK = 2,
|
||||
};
|
||||
|
||||
enum srp_target_state {
|
||||
@@ -86,15 +83,24 @@ enum srp_iu_type {
|
||||
SRP_IU_RSP,
|
||||
};
|
||||
|
||||
/*
|
||||
* @mr_page_mask: HCA memory registration page mask.
|
||||
* @mr_page_size: HCA memory registration page size.
|
||||
* @mr_max_size: Maximum size in bytes of a single FMR / FR registration
|
||||
* request.
|
||||
*/
|
||||
struct srp_device {
|
||||
struct list_head dev_list;
|
||||
struct ib_device *dev;
|
||||
struct ib_pd *pd;
|
||||
struct ib_mr *mr;
|
||||
struct ib_fmr_pool *fmr_pool;
|
||||
u64 fmr_page_mask;
|
||||
int fmr_page_size;
|
||||
int fmr_max_size;
|
||||
u64 mr_page_mask;
|
||||
int mr_page_size;
|
||||
int mr_max_size;
|
||||
int max_pages_per_mr;
|
||||
bool has_fmr;
|
||||
bool has_fr;
|
||||
bool use_fast_reg;
|
||||
};
|
||||
|
||||
struct srp_host {
|
||||
@@ -112,11 +118,14 @@ struct srp_request {
|
||||
struct list_head list;
|
||||
struct scsi_cmnd *scmnd;
|
||||
struct srp_iu *cmd;
|
||||
struct ib_pool_fmr **fmr_list;
|
||||
union {
|
||||
struct ib_pool_fmr **fmr_list;
|
||||
struct srp_fr_desc **fr_list;
|
||||
};
|
||||
u64 *map_page;
|
||||
struct srp_direct_buf *indirect_desc;
|
||||
dma_addr_t indirect_dma_addr;
|
||||
short nfmr;
|
||||
short nmdesc;
|
||||
short index;
|
||||
};
|
||||
|
||||
@@ -131,6 +140,10 @@ struct srp_target_port {
|
||||
struct ib_cq *send_cq ____cacheline_aligned_in_smp;
|
||||
struct ib_cq *recv_cq;
|
||||
struct ib_qp *qp;
|
||||
union {
|
||||
struct ib_fmr_pool *fmr_pool;
|
||||
struct srp_fr_pool *fr_pool;
|
||||
};
|
||||
u32 lkey;
|
||||
u32 rkey;
|
||||
enum srp_target_state state;
|
||||
@@ -197,15 +210,66 @@ struct srp_iu {
|
||||
enum dma_data_direction direction;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct srp_fr_desc - fast registration work request arguments
|
||||
* @entry: Entry in srp_fr_pool.free_list.
|
||||
* @mr: Memory region.
|
||||
* @frpl: Fast registration page list.
|
||||
*/
|
||||
struct srp_fr_desc {
|
||||
struct list_head entry;
|
||||
struct ib_mr *mr;
|
||||
struct ib_fast_reg_page_list *frpl;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct srp_fr_pool - pool of fast registration descriptors
|
||||
*
|
||||
* An entry is available for allocation if and only if it occurs in @free_list.
|
||||
*
|
||||
* @size: Number of descriptors in this pool.
|
||||
* @max_page_list_len: Maximum fast registration work request page list length.
|
||||
* @lock: Protects free_list.
|
||||
* @free_list: List of free descriptors.
|
||||
* @desc: Fast registration descriptor pool.
|
||||
*/
|
||||
struct srp_fr_pool {
|
||||
int size;
|
||||
int max_page_list_len;
|
||||
spinlock_t lock;
|
||||
struct list_head free_list;
|
||||
struct srp_fr_desc desc[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct srp_map_state - per-request DMA memory mapping state
|
||||
* @desc: Pointer to the element of the SRP buffer descriptor array
|
||||
* that is being filled in.
|
||||
* @pages: Array with DMA addresses of pages being considered for
|
||||
* memory registration.
|
||||
* @base_dma_addr: DMA address of the first page that has not yet been mapped.
|
||||
* @dma_len: Number of bytes that will be registered with the next
|
||||
* FMR or FR memory registration call.
|
||||
* @total_len: Total number of bytes in the sg-list being mapped.
|
||||
* @npages: Number of page addresses in the pages[] array.
|
||||
* @nmdesc: Number of FMR or FR memory descriptors used for mapping.
|
||||
* @ndesc: Number of SRP buffer descriptors that have been filled in.
|
||||
* @unmapped_sg: First element of the sg-list that is mapped via FMR or FR.
|
||||
* @unmapped_index: Index of the first element mapped via FMR or FR.
|
||||
* @unmapped_addr: DMA address of the first element mapped via FMR or FR.
|
||||
*/
|
||||
struct srp_map_state {
|
||||
struct ib_pool_fmr **next_fmr;
|
||||
union {
|
||||
struct ib_pool_fmr **next_fmr;
|
||||
struct srp_fr_desc **next_fr;
|
||||
};
|
||||
struct srp_direct_buf *desc;
|
||||
u64 *pages;
|
||||
dma_addr_t base_dma_addr;
|
||||
u32 fmr_len;
|
||||
u32 dma_len;
|
||||
u32 total_len;
|
||||
unsigned int npages;
|
||||
unsigned int nfmr;
|
||||
unsigned int nmdesc;
|
||||
unsigned int ndesc;
|
||||
struct scatterlist *unmapped_sg;
|
||||
int unmapped_index;
|
||||
|
Reference in New Issue
Block a user