[openib-general] [PATCH] umad: pass timeouts to userspace
Roland Dreier
roland at topspin.com
Mon Nov 15 09:09:12 PST 2004
OK, this adds a status and a timeout_ms field to struct ib_user_mad
and passes timeouts up to userspace. Seem OK?
- R.
Index: infiniband/include/ib_user_mad.h
===================================================================
--- infiniband/include/ib_user_mad.h (revision 1223)
+++ infiniband/include/ib_user_mad.h (working copy)
@@ -37,6 +37,10 @@
* ib_user_mad - MAD packet
* @data - Contents of MAD
* @id - ID of agent MAD received with/to be sent with
+ * @status - 0 on successfuly receive, ETIMEDOUT if no response
+ * received (transaction ID in data[] will be set to TID of original
+ * request) (ignored on send)
+ * @timeout_ms - Milliseconds to wait for response (unset on receive)
* @qpn - Remote QP number received from/to be sent to
* @qkey - Remote Q_Key to be sent with (unset on receive)
* @lid - Remote lid received from/to be sent to
@@ -54,6 +58,8 @@
struct ib_user_mad {
__u8 data[256];
__u32 id;
+ __u32 status;
+ __u32 timeout_ms;
__u32 qpn;
__u32 qkey;
__u16 lid;
Index: infiniband/core/user_mad.c
===================================================================
--- infiniband/core/user_mad.c (revision 1231)
+++ infiniband/core/user_mad.c (working copy)
@@ -84,17 +84,50 @@
static void ib_umad_add_one(struct ib_device *device);
static void ib_umad_remove_one(struct ib_device *device);
+static int queue_packet(struct ib_umad_file *file,
+ struct ib_mad_agent *agent,
+ struct ib_umad_packet *packet)
+{
+ int ret = 1;
+
+ down_read(&file->agent_mutex);
+ for (packet->mad.id = 0;
+ packet->mad.id < IB_UMAD_MAX_AGENTS;
+ packet->mad.id++)
+ if (agent == file->agent[packet->mad.id]) {
+ spin_lock_irq(&file->recv_lock);
+ list_add_tail(&packet->list, &file->recv_list);
+ spin_unlock_irq(&file->recv_lock);
+ wake_up_interruptible(&file->recv_wait);
+ ret = 0;
+ break;
+ }
+
+ up_read(&file->agent_mutex);
+
+ return ret;
+}
+
static void send_handler(struct ib_mad_agent *agent,
- struct ib_mad_send_wc *mad_send_wc)
+ struct ib_mad_send_wc *send_wc)
{
+ struct ib_umad_file *file = agent->context;
struct ib_umad_packet *packet =
- (void *) (unsigned long) mad_send_wc->wr_id;
+ (void *) (unsigned long) send_wc->wr_id;
pci_unmap_single(agent->device->dma_device,
pci_unmap_addr(packet, mapping),
sizeof packet->mad.data,
PCI_DMA_TODEVICE);
ib_destroy_ah(packet->ah);
+
+ if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
+ packet->mad.status = ETIMEDOUT;
+
+ if (!queue_packet(file, agent, packet))
+ return;
+ }
+
kfree(packet);
}
@@ -114,6 +147,7 @@
memset(packet, 0, sizeof *packet);
memcpy(packet->mad.data, mad_recv_wc->recv_buf->mad, sizeof packet->mad.data);
+ packet->mad.status = 0;
packet->mad.qpn = cpu_to_be32(mad_recv_wc->wc->src_qp);
packet->mad.lid = cpu_to_be16(mad_recv_wc->wc->slid);
packet->mad.sl = mad_recv_wc->wc->sl;
@@ -128,23 +162,9 @@
packet->mad.flow_label = 0;
}
- down_read(&file->agent_mutex);
- for (packet->mad.id = 0;
- packet->mad.id < IB_UMAD_MAX_AGENTS;
- packet->mad.id++)
- if (agent == file->agent[packet->mad.id]) {
- spin_lock_irq(&file->recv_lock);
- list_add_tail(&packet->list, &file->recv_list);
- spin_unlock_irq(&file->recv_lock);
- wake_up_interruptible(&file->recv_wait);
- goto agent;
- }
+ if (queue_packet(file, agent, packet))
+ kfree(packet);
- kfree(packet);
-
-agent:
- up_read(&file->agent_mutex);
-
out:
ib_free_recv_mad(mad_recv_wc);
}
@@ -259,6 +279,7 @@
wr.wr.ud.ah = packet->ah;
wr.wr.ud.remote_qpn = be32_to_cpu(packet->mad.qpn);
wr.wr.ud.remote_qkey = be32_to_cpu(packet->mad.qkey);
+ wr.wr.ud.timeout_ms = packet->mad.timeout_ms;
wr.wr_id = (unsigned long) packet;
Index: docs/user_mad.txt
===================================================================
--- docs/user_mad.txt (revision 1223)
+++ docs/user_mad.txt (working copy)
@@ -39,6 +39,10 @@
fields will be filled in with information on the received MAD. For
example, the remote LID will be in mad.lid.
+ If a send times out, a receive will be generated with mad.status set
+ to ETIMEDOUT. Otherwise when a MAD has been successfully received,
+ mad.status will be 0.
+
poll()/select() may be used to wait until a MAD can be read.
Sending MADs
More information about the general
mailing list