summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h23
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c25
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c70
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c48
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h3
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c137
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c9
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c31
10 files changed, 178 insertions, 182 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index e0c7dfabf2b..753a983a5fd 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -732,29 +732,6 @@ extern int ipoib_debug_level;
do { (void) (priv); } while (0)
#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */
-
-#define IPOIB_GID_FMT "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:" \
- "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x"
-
-#define IPOIB_GID_RAW_ARG(gid) ((u8 *)(gid))[0], \
- ((u8 *)(gid))[1], \
- ((u8 *)(gid))[2], \
- ((u8 *)(gid))[3], \
- ((u8 *)(gid))[4], \
- ((u8 *)(gid))[5], \
- ((u8 *)(gid))[6], \
- ((u8 *)(gid))[7], \
- ((u8 *)(gid))[8], \
- ((u8 *)(gid))[9], \
- ((u8 *)(gid))[10],\
- ((u8 *)(gid))[11],\
- ((u8 *)(gid))[12],\
- ((u8 *)(gid))[13],\
- ((u8 *)(gid))[14],\
- ((u8 *)(gid))[15]
-
-#define IPOIB_GID_ARG(gid) IPOIB_GID_RAW_ARG((gid).raw)
-
#define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff)
#endif /* _IPOIB_H */
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 7b14c2c3950..47d588ba2a7 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1128,8 +1128,8 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
goto err_send_cm;
}
- ipoib_dbg(priv, "Request connection 0x%x for gid " IPOIB_GID_FMT " qpn 0x%x\n",
- p->qp->qp_num, IPOIB_GID_ARG(pathrec->dgid), qpn);
+ ipoib_dbg(priv, "Request connection 0x%x for gid %pI6 qpn 0x%x\n",
+ p->qp->qp_num, pathrec->dgid.raw, qpn);
return 0;
@@ -1276,8 +1276,8 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) {
list_move(&tx->list, &priv->cm.reap_list);
queue_work(ipoib_workqueue, &priv->cm.reap_task);
- ipoib_dbg(priv, "Reap connection for gid " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(tx->neigh->dgid));
+ ipoib_dbg(priv, "Reap connection for gid %pI6\n",
+ tx->neigh->dgid.raw);
tx->neigh = NULL;
}
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 28eb6f03c58..a1925810be3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -446,11 +446,11 @@ poll_more:
if (dev->features & NETIF_F_LRO)
lro_flush_all(&priv->lro.lro_mgr);
- netif_rx_complete(dev, napi);
+ netif_rx_complete(napi);
if (unlikely(ib_req_notify_cq(priv->recv_cq,
IB_CQ_NEXT_COMP |
IB_CQ_REPORT_MISSED_EVENTS)) &&
- netif_rx_reschedule(dev, napi))
+ netif_rx_reschedule(napi))
goto poll_more;
}
@@ -462,7 +462,7 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
struct net_device *dev = dev_ptr;
struct ipoib_dev_priv *priv = netdev_priv(dev);
- netif_rx_schedule(dev, &priv->napi);
+ netif_rx_schedule(&priv->napi);
}
static void drain_tx_cq(struct net_device *dev)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 85257f6b957..19e06bc38b3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -360,9 +360,9 @@ void ipoib_mark_paths_invalid(struct net_device *dev)
spin_lock_irq(&priv->lock);
list_for_each_entry_safe(path, tp, &priv->path_list, list) {
- ipoib_dbg(priv, "mark path LID 0x%04x GID " IPOIB_GID_FMT " invalid\n",
+ ipoib_dbg(priv, "mark path LID 0x%04x GID %pI6 invalid\n",
be16_to_cpu(path->pathrec.dlid),
- IPOIB_GID_ARG(path->pathrec.dgid));
+ path->pathrec.dgid.raw);
path->valid = 0;
}
@@ -414,11 +414,11 @@ static void path_rec_completion(int status,
unsigned long flags;
if (!status)
- ipoib_dbg(priv, "PathRec LID 0x%04x for GID " IPOIB_GID_FMT "\n",
- be16_to_cpu(pathrec->dlid), IPOIB_GID_ARG(pathrec->dgid));
+ ipoib_dbg(priv, "PathRec LID 0x%04x for GID %pI6\n",
+ be16_to_cpu(pathrec->dlid), pathrec->dgid.raw);
else
- ipoib_dbg(priv, "PathRec status %d for GID " IPOIB_GID_FMT "\n",
- status, IPOIB_GID_ARG(path->pathrec.dgid));
+ ipoib_dbg(priv, "PathRec status %d for GID %pI6\n",
+ status, path->pathrec.dgid.raw);
skb_queue_head_init(&skqueue);
@@ -528,8 +528,8 @@ static int path_rec_start(struct net_device *dev,
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- ipoib_dbg(priv, "Start path record lookup for " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(path->pathrec.dgid));
+ ipoib_dbg(priv, "Start path record lookup for %pI6\n",
+ path->pathrec.dgid.raw);
init_completion(&path->done);
@@ -766,12 +766,11 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
(be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
- ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x "
- IPOIB_GID_FMT "\n",
+ ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
skb->dst ? "neigh" : "dst",
be16_to_cpup((__be16 *) skb->data),
IPOIB_QPN(phdr->hwaddr),
- IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
+ phdr->hwaddr + 4);
dev_kfree_skb_any(skb);
++dev->stats.tx_dropped;
return NETDEV_TX_OK;
@@ -847,9 +846,9 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
else
return;
ipoib_dbg(priv,
- "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
+ "neigh_cleanup for %06x %pI6\n",
IPOIB_QPN(n->ha),
- IPOIB_GID_RAW_ARG(n->ha + 4));
+ n->ha + 4);
spin_lock_irqsave(&priv->lock, flags);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index d9d1223c3fd..a2eb3b9789e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -71,9 +71,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
struct ipoib_neigh *neigh, *tmp;
int tx_dropped = 0;
- ipoib_dbg_mcast(netdev_priv(dev),
- "deleting multicast group " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
+ ipoib_dbg_mcast(netdev_priv(dev), "deleting multicast group %pI6\n",
+ mcast->mcmember.mgid.raw);
spin_lock_irq(&priv->lock);
@@ -205,9 +204,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
if (test_and_set_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
- ipoib_warn(priv, "multicast group " IPOIB_GID_FMT
- " already attached\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
+ ipoib_warn(priv, "multicast group %pI6 already attached\n",
+ mcast->mcmember.mgid.raw);
return 0;
}
@@ -215,9 +213,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
ret = ipoib_mcast_attach(dev, be16_to_cpu(mcast->mcmember.mlid),
&mcast->mcmember.mgid, set_qkey);
if (ret < 0) {
- ipoib_warn(priv, "couldn't attach QP to multicast group "
- IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
+ ipoib_warn(priv, "couldn't attach QP to multicast group %pI6\n",
+ mcast->mcmember.mgid.raw);
clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags);
return ret;
@@ -248,9 +245,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
mcast->ah = ah;
spin_unlock_irq(&priv->lock);
- ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT
- " AV %p, LID 0x%04x, SL %d\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid),
+ ipoib_dbg_mcast(priv, "MGID %pI6 AV %p, LID 0x%04x, SL %d\n",
+ mcast->mcmember.mgid.raw,
mcast->ah->ah,
be16_to_cpu(mcast->mcmember.mlid),
mcast->mcmember.sl);
@@ -295,9 +291,8 @@ ipoib_mcast_sendonly_join_complete(int status,
if (status) {
if (mcast->logcount++ < 20)
- ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for "
- IPOIB_GID_FMT ", status %d\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid), status);
+ ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for %pI6, status %d\n",
+ mcast->mcmember.mgid.raw, status);
/* Flush out any queued packets */
netif_tx_lock_bh(dev);
@@ -356,9 +351,8 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
ipoib_warn(priv, "ib_sa_join_multicast failed (ret = %d)\n",
ret);
} else {
- ipoib_dbg_mcast(priv, "no multicast record for " IPOIB_GID_FMT
- ", starting join\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
+ ipoib_dbg_mcast(priv, "no multicast record for %pI6, starting join\n",
+ mcast->mcmember.mgid.raw);
}
return ret;
@@ -386,9 +380,8 @@ static int ipoib_mcast_join_complete(int status,
struct net_device *dev = mcast->dev;
struct ipoib_dev_priv *priv = netdev_priv(dev);
- ipoib_dbg_mcast(priv, "join completion for " IPOIB_GID_FMT
- " (status %d)\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid), status);
+ ipoib_dbg_mcast(priv, "join completion for %pI6 (status %d)\n",
+ mcast->mcmember.mgid.raw, status);
/* We trap for port events ourselves. */
if (status == -ENETRESET)
@@ -417,15 +410,11 @@ static int ipoib_mcast_join_complete(int status,
if (mcast->logcount++ < 20) {
if (status == -ETIMEDOUT) {
- ipoib_dbg_mcast(priv, "multicast join failed for " IPOIB_GID_FMT
- ", status %d\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid),
- status);
+ ipoib_dbg_mcast(priv, "multicast join failed for %pI6, status %d\n",
+ mcast->mcmember.mgid.raw, status);
} else {
- ipoib_warn(priv, "multicast join failed for "
- IPOIB_GID_FMT ", status %d\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid),
- status);
+ ipoib_warn(priv, "multicast join failed for %pI6, status %d\n",
+ mcast->mcmember.mgid.raw, status);
}
}
@@ -457,8 +446,7 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
ib_sa_comp_mask comp_mask;
int ret = 0;
- ipoib_dbg_mcast(priv, "joining MGID " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
+ ipoib_dbg_mcast(priv, "joining MGID %pI6\n", mcast->mcmember.mgid.raw);
rec.mgid = mcast->mcmember.mgid;
rec.port_gid = priv->local_gid;
@@ -643,8 +631,8 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
ib_sa_free_multicast(mcast->mc);
if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
- ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
+ ipoib_dbg_mcast(priv, "leaving MGID %pI6\n",
+ mcast->mcmember.mgid.raw);
/* Remove ourselves from the multicast group */
ret = ib_detach_mcast(priv->qp, &mcast->mcmember.mgid,
@@ -675,8 +663,8 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
mcast = __ipoib_mcast_find(dev, mgid);
if (!mcast) {
/* Let's create a new send only group now */
- ipoib_dbg_mcast(priv, "setting up send only multicast group for "
- IPOIB_GID_FMT "\n", IPOIB_GID_RAW_ARG(mgid));
+ ipoib_dbg_mcast(priv, "setting up send only multicast group for %pI6\n",
+ mgid);
mcast = ipoib_mcast_alloc(dev, 0);
if (!mcast) {
@@ -809,14 +797,14 @@ void ipoib_mcast_restart_task(struct work_struct *work)
/* ignore group which is directly joined by userspace */
if (test_bit(IPOIB_FLAG_UMCAST, &priv->flags) &&
!ib_sa_get_mcmember_rec(priv->ca, priv->port, &mgid, &rec)) {
- ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid "
- IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
+ ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid %pI6\n",
+ mgid.raw);
continue;
}
/* Not found or send-only group, let's add a new entry */
- ipoib_dbg_mcast(priv, "adding multicast entry for mgid "
- IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
+ ipoib_dbg_mcast(priv, "adding multicast entry for mgid %pI6\n",
+ mgid.raw);
nmcast = ipoib_mcast_alloc(dev, 0);
if (!nmcast) {
@@ -849,8 +837,8 @@ void ipoib_mcast_restart_task(struct work_struct *work)
list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) {
if (!test_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags) &&
!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
- ipoib_dbg_mcast(priv, "deleting multicast group " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
+ ipoib_dbg_mcast(priv, "deleting multicast group %pI6\n",
+ mcast->mcmember.mgid.raw);
rb_erase(&mcast->rb_node, &priv->multicast_tree);
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 1e5b6446231..12876392516 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -119,6 +119,14 @@ error:
iscsi_conn_failure(conn, rc);
}
+static int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode)
+{
+ struct iscsi_iser_task *iser_task = task->dd_data;
+
+ task->hdr = (struct iscsi_hdr *)&iser_task->desc.iscsi_header;
+ task->hdr_max = sizeof(iser_task->desc.iscsi_header);
+ return 0;
+}
/**
* iscsi_iser_task_init - Initialize task
@@ -180,25 +188,26 @@ static int
iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn,
struct iscsi_task *task)
{
- struct iscsi_data hdr;
+ struct iscsi_r2t_info *r2t = &task->unsol_r2t;
+ struct iscsi_data hdr;
int error = 0;
/* Send data-out PDUs while there's still unsolicited data to send */
- while (task->unsol_count > 0) {
- iscsi_prep_unsolicit_data_pdu(task, &hdr);
+ while (iscsi_task_has_unsol_data(task)) {
+ iscsi_prep_data_out_pdu(task, r2t, &hdr);
debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
- hdr.itt, task->data_count);
+ hdr.itt, r2t->data_count);
/* the buffer description has been passed with the command */
/* Send the command */
error = iser_send_data_out(conn, task, &hdr);
if (error) {
- task->unsol_datasn--;
+ r2t->datasn--;
goto iscsi_iser_task_xmit_unsol_data_exit;
}
- task->unsol_count -= task->data_count;
+ r2t->sent += r2t->data_count;
debug_scsi("Need to send %d more as data-out PDUs\n",
- task->unsol_count);
+ r2t->data_length - r2t->sent);
}
iscsi_iser_task_xmit_unsol_data_exit:
@@ -220,7 +229,7 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
task->itt, scsi_bufflen(task->sc),
- task->imm_count, task->unsol_count);
+ task->imm_count, task->unsol_r2t.data_length);
}
debug_scsi("task deq [cid %d itt 0x%x]\n",
@@ -235,7 +244,7 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
}
/* Send unsolicited data-out PDU(s) if necessary */
- if (task->unsol_count)
+ if (iscsi_task_has_unsol_data(task))
error = iscsi_iser_task_xmit_unsol_data(conn, task);
iscsi_iser_task_xmit_exit:
@@ -244,13 +253,15 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
return error;
}
-static void
-iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
+static void iscsi_iser_cleanup_task(struct iscsi_task *task)
{
struct iscsi_iser_task *iser_task = task->dd_data;
- /* mgmt tasks do not need special cleanup */
- if (!task->sc)
+ /*
+ * mgmt tasks do not need special cleanup and we do not
+ * allocate anything in the init task callout
+ */
+ if (!task->sc || task->state == ISCSI_TASK_PENDING)
return;
if (iser_task->status == ISER_TASK_STATUS_STARTED) {
@@ -391,9 +402,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
struct iscsi_cls_session *cls_session;
struct iscsi_session *session;
struct Scsi_Host *shost;
- int i;
- struct iscsi_task *task;
- struct iscsi_iser_task *iser_task;
struct iser_conn *ib_conn;
shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
@@ -430,13 +438,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
session = cls_session->dd_data;
shost->can_queue = session->scsi_cmds_max;
- /* libiscsi setup itts, data and pool so just set desc fields */
- for (i = 0; i < session->cmds_max; i++) {
- task = session->cmds[i];
- iser_task = task->dd_data;
- task->hdr = (struct iscsi_cmd *)&iser_task->desc.iscsi_header;
- task->hdr_max = sizeof(iser_task->desc.iscsi_header);
- }
return cls_session;
remove_host:
@@ -652,6 +653,7 @@ static struct iscsi_transport iscsi_iser_transport = {
.init_task = iscsi_iser_task_init,
.xmit_task = iscsi_iser_task_xmit,
.cleanup_task = iscsi_iser_cleanup_task,
+ .alloc_pdu = iscsi_iser_pdu_alloc,
/* recovery */
.session_recovery_timedout = iscsi_session_recovery_timedout,
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 81a82628a5f..861119593f2 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -252,6 +252,9 @@ struct iser_conn {
wait_queue_head_t wait; /* waitq for conn/disconn */
atomic_t post_recv_buf_count; /* posted rx count */
atomic_t post_send_buf_count; /* posted tx count */
+ atomic_t unexpected_pdu_count;/* count of received *
+ * unexpected pdus *
+ * not yet retired */
char name[ISER_OBJECT_NAME_SIZE];
struct iser_page_vec *page_vec; /* represents SG to fmr maps*
* maps serialized as tx is*/
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index cdd28318904..e209cb8dd94 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -183,14 +183,8 @@ static int iser_post_receive_control(struct iscsi_conn *conn)
struct iser_regd_buf *regd_data;
struct iser_dto *recv_dto = NULL;
struct iser_device *device = iser_conn->ib_conn->device;
- int rx_data_size, err = 0;
-
- rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
- if (rx_desc == NULL) {
- iser_err("Failed to alloc desc for post recv\n");
- return -ENOMEM;
- }
- rx_desc->type = ISCSI_RX;
+ int rx_data_size, err;
+ int posts, outstanding_unexp_pdus;
/* for the login sequence we must support rx of upto 8K; login is done
* after conn create/bind (connect) and conn stop/bind (reconnect),
@@ -201,46 +195,80 @@ static int iser_post_receive_control(struct iscsi_conn *conn)
else /* FIXME till user space sets conn->max_recv_dlength correctly */
rx_data_size = 128;
- rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
- if (rx_desc->data == NULL) {
- iser_err("Failed to alloc data buf for post recv\n");
- err = -ENOMEM;
- goto post_rx_kmalloc_failure;
- }
+ outstanding_unexp_pdus =
+ atomic_xchg(&iser_conn->ib_conn->unexpected_pdu_count, 0);
- recv_dto = &rx_desc->dto;
- recv_dto->ib_conn = iser_conn->ib_conn;
- recv_dto->regd_vector_len = 0;
+ /*
+ * in addition to the response buffer, replace those consumed by
+ * unexpected pdus.
+ */
+ for (posts = 0; posts < 1 + outstanding_unexp_pdus; posts++) {
+ rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
+ if (rx_desc == NULL) {
+ iser_err("Failed to alloc desc for post recv %d\n",
+ posts);
+ err = -ENOMEM;
+ goto post_rx_cache_alloc_failure;
+ }
+ rx_desc->type = ISCSI_RX;
+ rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
+ if (rx_desc->data == NULL) {
+ iser_err("Failed to alloc data buf for post recv %d\n",
+ posts);
+ err = -ENOMEM;
+ goto post_rx_kmalloc_failure;
+ }
- regd_hdr = &rx_desc->hdr_regd_buf;
- memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
- regd_hdr->device = device;
- regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */
- regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
+ recv_dto = &rx_desc->dto;
+ recv_dto->ib_conn = iser_conn->ib_conn;
+ recv_dto->regd_vector_len = 0;
- iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
+ regd_hdr = &rx_desc->hdr_regd_buf;
+ memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
+ regd_hdr->device = device;
+ regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */
+ regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
- iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
+ iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
- regd_data = &rx_desc->data_regd_buf;
- memset(regd_data, 0, sizeof(struct iser_regd_buf));
- regd_data->device = device;
- regd_data->virt_addr = rx_desc->data;
- regd_data->data_size = rx_data_size;
+ iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
- iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
+ regd_data = &rx_desc->data_regd_buf;
+ memset(regd_data, 0, sizeof(struct iser_regd_buf));
+ regd_data->device = device;
+ regd_data->virt_addr = rx_desc->data;
+ regd_data->data_size = rx_data_size;
- iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
+ iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
- err = iser_post_recv(rx_desc);
- if (!err)
- return 0;
+ iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
+
+ err = iser_post_recv(rx_desc);
+ if (err) {
+ iser_err("Failed iser_post_recv for post %d\n", posts);
+ goto post_rx_post_recv_failure;
+ }
+ }
+ /* all posts successful */
+ return 0;
- /* iser_post_recv failed */
+post_rx_post_recv_failure:
iser_dto_buffs_release(recv_dto);
kfree(rx_desc->data);
post_rx_kmalloc_failure:
kmem_cache_free(ig.desc_cache, rx_desc);
+post_rx_cache_alloc_failure:
+ if (posts > 0) {
+ /*
+ * response buffer posted, but did not replace all unexpected
+ * pdu recv bufs. Ignore error, retry occurs next send
+ */
+ outstanding_unexp_pdus -= (posts - 1);
+ err = 0;
+ }
+ atomic_add(outstanding_unexp_pdus,
+ &iser_conn->ib_conn->unexpected_pdu_count);
+
return err;
}
@@ -274,8 +302,10 @@ int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
struct iscsi_iser_conn *iser_conn = conn->dd_data;
int i;
- /* no need to keep it in a var, we are after login so if this should
- * be negotiated, by now the result should be available here */
+ /*
+ * FIXME this value should be declared to the target during login with
+ * the MaxOutstandingUnexpectedPDUs key when supported
+ */
int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS;
iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num);
@@ -323,8 +353,7 @@ int iser_send_command(struct iscsi_conn *conn,
unsigned long edtl;
int err = 0;
struct iser_data_buf *data_buf;
-
- struct iscsi_cmd *hdr = task->hdr;
+ struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr;
struct scsi_cmnd *sc = task->sc;
if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
@@ -363,7 +392,7 @@ int iser_send_command(struct iscsi_conn *conn,
err = iser_prepare_write_cmd(task,
task->imm_count,
task->imm_count +
- task->unsol_count,
+ task->unsol_r2t.data_length,
edtl);
if (err)
goto send_command_error;
@@ -478,6 +507,7 @@ int iser_send_control(struct iscsi_conn *conn,
int err = 0;
struct iser_regd_buf *regd_buf;
struct iser_device *device;
+ unsigned char opcode;
if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
@@ -512,10 +542,15 @@ int iser_send_control(struct iscsi_conn *conn,
data_seg_len);
}
- if (iser_post_receive_control(conn) != 0) {
- iser_err("post_rcv_buff failed!\n");
- err = -ENOMEM;
- goto send_control_error;
+ opcode = task->hdr->opcode & ISCSI_OPCODE_MASK;
+
+ /* post recv buffer for response if one is expected */
+ if (!(opcode == ISCSI_OP_NOOP_OUT && task->hdr->itt == RESERVED_ITT)) {
+ if (iser_post_receive_control(conn) != 0) {
+ iser_err("post_rcv_buff failed!\n");
+ err = -ENOMEM;
+ goto send_control_error;
+ }
}
err = iser_post_send(mdesc);
@@ -586,6 +621,20 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
* parallel to the execution of iser_conn_term. So the code that waits *
* for the posted rx bufs refcount to become zero handles everything */
atomic_dec(&conn->ib_conn->post_recv_buf_count);
+
+ /*
+ * if an unexpected PDU was received then the recv wr consumed must
+ * be replaced, this is done in the next send of a control-type PDU
+ */
+ if (opcode == ISCSI_OP_NOOP_IN && hdr->itt == RESERVED_ITT) {
+ /* nop-in with itt = 0xffffffff */
+ atomic_inc(&conn->ib_conn->unexpected_pdu_count);
+ }
+ else if (opcode == ISCSI_OP_ASYNC_EVENT) {
+ /* asyncronous message */
+ atomic_inc(&conn->ib_conn->unexpected_pdu_count);
+ }
+ /* a reject PDU consumes the recv buf posted for the response */
}
void iser_snd_completion(struct iser_desc *tx_desc)
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 26ff6214a81..319b188145b 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -498,6 +498,7 @@ void iser_conn_init(struct iser_conn *ib_conn)
init_waitqueue_head(&ib_conn->wait);
atomic_set(&ib_conn->post_recv_buf_count, 0);
atomic_set(&ib_conn->post_send_buf_count, 0);
+ atomic_set(&ib_conn->unexpected_pdu_count, 0);
atomic_set(&ib_conn->refcount, 1);
INIT_LIST_HEAD(&ib_conn->conn_list);
spin_lock_init(&ib_conn->lock);
@@ -515,14 +516,14 @@ int iser_connect(struct iser_conn *ib_conn,
struct sockaddr *src, *dst;
int err = 0;
- sprintf(ib_conn->name,"%d.%d.%d.%d:%d",
- NIPQUAD(dst_addr->sin_addr.s_addr), dst_addr->sin_port);
+ sprintf(ib_conn->name, "%pI4:%d",
+ &dst_addr->sin_addr.s_addr, dst_addr->sin_port);
/* the device is known only --after-- address resolution */
ib_conn->device = NULL;
- iser_err("connecting to: %d.%d.%d.%d, port 0x%x\n",
- NIPQUAD(dst_addr->sin_addr), dst_addr->sin_port);
+ iser_err("connecting to: %pI4, port 0x%x\n",
+ &dst_addr->sin_addr, dst_addr->sin_port);
ib_conn->state = ISER_CONN_PENDING;
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 5b8b533f290..7c13db885bf 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1514,15 +1514,7 @@ static ssize_t show_dgid(struct device *dev, struct device_attribute *attr,
target->state == SRP_TARGET_REMOVED)
return -ENODEV;
- return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[0]),
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[1]),
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[2]),
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[3]),
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[4]),
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[5]),
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[6]),
- be16_to_cpu(((__be16 *) target->path.dgid.raw)[7]));
+ return sprintf(buf, "%pI6\n", target->path.dgid.raw);
}
static ssize_t show_orig_dgid(struct device *dev,
@@ -1534,15 +1526,7 @@ static ssize_t show_orig_dgid(struct device *dev,
target->state == SRP_TARGET_REMOVED)
return -ENODEV;
- return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
- be16_to_cpu(target->orig_dgid[0]),
- be16_to_cpu(target->orig_dgid[1]),
- be16_to_cpu(target->orig_dgid[2]),
- be16_to_cpu(target->orig_dgid[3]),
- be16_to_cpu(target->orig_dgid[4]),
- be16_to_cpu(target->orig_dgid[5]),
- be16_to_cpu(target->orig_dgid[6]),
- be16_to_cpu(target->orig_dgid[7]));
+ return sprintf(buf, "%pI6\n", target->orig_dgid);
}
static ssize_t show_zero_req_lim(struct device *dev,
@@ -1883,19 +1867,12 @@ static ssize_t srp_create_target(struct device *dev,
shost_printk(KERN_DEBUG, target->scsi_host, PFX
"new target: id_ext %016llx ioc_guid %016llx pkey %04x "
- "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+ "service_id %016llx dgid %pI6\n",
(unsigned long long) be64_to_cpu(target->id_ext),
(unsigned long long) be64_to_cpu(target->ioc_guid),
be16_to_cpu(target->path.pkey),
(unsigned long long) be64_to_cpu(target->service_id),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[0]),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[2]),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[4]),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[6]),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[8]),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[10]),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[12]),
- (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[14]));
+ target->path.dgid.raw);
ret = srp_create_target_ib(target);
if (ret)