[ofa-general] [PATCHv2] ibsim: Support short RMPP packets
Hal Rosenstock
hrosenstock at xsigo.com
Thu Jun 19 07:35:28 PDT 2008
ibsim: Support for short RMPP packets (up thru 256 bytes total)
Changes from v1:
- Added length to simulation header (by reducing context size so as not
to break ABI) and encoded length on sends and decoded and checked
lengths on receive
- Restored short/partial packet read check in umad2sim_read
- In umad2sim_write, fixed setting of umad->length
- Eliminated sim_req256 typedef
Signed-off-by: Hal Rosenstock <hal at xsigo.com>
diff --git a/TODO b/TODO
index 616ed71..b385ade 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,7 @@
* transaction management
- multiple transactions per client
- hops simulation
- - RMPP
+ - long RMPP
* more attributes handled
* MKey support
* cleaner (less) debug/warning messages
diff --git a/ibsim/ibsim.c b/ibsim/ibsim.c
index e4ab6bc..cde9ac5 100644
--- a/ibsim/ibsim.c
+++ b/ibsim/ibsim.c
@@ -492,9 +492,9 @@ static int sim_read_pkt(int fd, int client)
if (!dcl)
continue;
- VERB("%s %d bytes (%zu) to client %d fd %d",
+ VERB("%s %d bytes to client %d fd %d",
dcl == cl ? "replying" : "forwarding",
- size, sizeof(struct sim_request), dcl->id, dcl->fd);
+ size, dcl->id, dcl->fd);
// reply
ret = write(dcl->fd, buf, size);
diff --git a/ibsim/sim_mad.c b/ibsim/sim_mad.c
index 675d95b..28fdd52
--- a/ibsim/sim_mad.c
+++ b/ibsim/sim_mad.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
*
* This file is part of ibsim.
*
@@ -1128,14 +1129,14 @@ Smpfn *get_handle_fn(ib_rpc_t rpc, int response)
return fn;
}
- return 0; // No MGTCLASS matched .
+ return 0; // No MGTCLASS matched.
}
int process_packet(Client * cl, void *p, int size, Client ** dcl)
{
struct sim_request *r = p;
Port *port;
- uint8_t data[256];
+ uint8_t data[MAD_BLOCK_SIZE];
int status, tlid, tqp;
int response;
Smpfn *fn;
@@ -1144,9 +1145,10 @@ int process_packet(Client * cl, void *p, int size, Client ** dcl)
*dcl = cl;
- DEBUG("client %d, size %d", cl->id, size);
- if (size != sizeof(*r)) {
- IBWARN("bad packet size %d (!= %zu)", size, sizeof(*r));
+ DEBUG("client %d size %d", cl->id, size);
+ if (size > sizeof(*r) + MAD_BLOCK_SIZE) {
+ IBWARN("unsupported packet size %d (> %zu)", size,
+ sizeof(*r) + MAD_BLOCK_SIZE);
return -1;
}
@@ -1183,7 +1185,7 @@ int process_packet(Client * cl, void *p, int size, Client ** dcl)
VERB("forward pkt to client %d pid %d attr %d",
(*dcl)->id, (*dcl)->pid, rpc.attr.id);
forward_MAD(r->mad, &rpc, &path);
- return sizeof(*r); // forward only
+ return size; // forward only
}
if (port->errrate && (random() % 100) < port->errrate) {
@@ -1214,12 +1216,12 @@ int process_packet(Client * cl, void *p, int size, Client ** dcl)
VERB("PKT roll back did not succeed");
goto _dropped;
}
- return sizeof(*r);
+ return sizeof(*r) + MAD_BLOCK_SIZE;
_dropped:
r->status = htonl(110);
*dcl = cl;
- return sizeof(*r);
+ return sizeof(*r) + MAD_BLOCK_SIZE;
}
static int encode_trap128(Port * port, char *data)
@@ -1279,48 +1281,60 @@ static int encode_trap_header(char *buf)
int send_trap(Port * port, int trapnum)
{
- struct sim_request req;
+ struct sim_request *req;
Client *cl;
int ret, lid = port->lid;
- char *data = req.mad + 64; /* data offset */
EncodeTrapfn *encode_trapfn = encodetrap[trapnum];
Port *destport;
if (!encode_trapfn) {
- IBWARN("trap number %d not upported", trapnum);
+ IBWARN("trap number %d not supported", trapnum);
return -1;
}
- memset(req.mad, 0, sizeof(req.mad));
- encode_trap_header(req.mad);
- if (encode_trapfn(port, data) < 0)
+ req = malloc(sizeof(*req) + MAD_BLOCK_SIZE);
+ if (!req) {
+ IBWARN("no mem for trap MAD: %m");
return -1;
+ }
+
+ memset(req->mad, 0, MAD_BLOCK_SIZE);
+ encode_trap_header(req->mad);
+ if (encode_trapfn(port, req->mad + 64) < 0) {
+ free(req);
+ return -1;
+ }
if (!(destport = lid_route_MAD(port, port->smlid))) {
+ free(req);
IBWARN("routing failed: no route to dest lid %d", port->smlid);
return -1;
}
- req.dlid = htons(port->smlid);
- req.slid = htons(lid);
- req.sqp = 0;
- req.dqp = 0;
- req.status = 0;
- req.context = 0;
+ req->dlid = htons(port->smlid);
+ req->slid = htons(lid);
+ req->sqp = 0;
+ req->dqp = 0;
+ req->status = 0;
+ req->length = MAD_BLOCK_SIZE;
+ req->context = 0;
// find SM client
cl = find_client(destport, 0, 1, 0);
- if (!cl)
+ if (!cl) {
+ free(req);
return 0;
+ }
if (simverb > 2) {
xdump(stdout, "--- packet ---\n", &req, 256);
fflush(stdout);
}
- ret = write(cl->fd, &req, sizeof(req));
- if (ret == sizeof(req))
+ ret = write(cl->fd, req, sizeof(*req) + MAD_BLOCK_SIZE);
+ free(req);
+ if (ret == sizeof(*req) + MAD_BLOCK_SIZE)
return 0;
if (ret < 0 && (errno == ECONNREFUSED || errno == ENOTCONN)) {
diff --git a/include/ibsim.h b/include/ibsim.h
index 84568e6..2c6a841 100644
--- a/include/ibsim.h
+++ b/include/ibsim.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2006,2007 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
*
* This file is part of ibsim.
*
@@ -61,14 +62,17 @@ struct sim_port {
#define SIM_MAGIC 0xdeadbeef
#define SIM_CTL_MAX_DATA 64
+#define MAD_BLOCK_SIZE 256
+
struct sim_request {
uint32_t dlid;
uint32_t slid;
uint32_t dqp;
uint32_t sqp;
uint32_t status;
- uint64_t context;
- char mad[256];
+ uint32_t length;
+ uint32_t context;
+ char mad[0];
};
enum SIM_CTL_TYPES {
diff --git a/umad2sim/umad2sim.c b/umad2sim/umad2sim.c
index 4cbf8da..6f0fbad 100644
--- a/umad2sim/umad2sim.c
+++ b/umad2sim/umad2sim.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2006,2007 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
*
* This file is part of ibsim.
*
@@ -376,30 +377,46 @@ static int dev_sysfs_create(struct umad2sim_dev *dev)
static ssize_t umad2sim_read(struct umad2sim_dev *dev, void *buf, size_t count)
{
- struct sim_request req;
+ struct sim_request *req;
ib_user_mad_t *umad = (ib_user_mad_t *) buf;
unsigned mgmt_class;
int cnt;
DEBUG("umad2sim_read: %zu...\n", count);
+ req = malloc(sizeof(*req) + MAD_BLOCK_SIZE);
+ if (!req) {
+ ERROR("umad2sim_read: no mem: %m\n");
+ return 0; /* ???? */
+ }
- cnt = real_read(dev->sim_client.fd_pktin, &req, sizeof(req));
+ cnt = real_read(dev->sim_client.fd_pktin, req,
+ sizeof(*req) + MAD_BLOCK_SIZE);
DEBUG("umad2sim_read: got %d...\n", cnt);
- if (cnt < sizeof(req)) {
- ERROR("umad2sim_read: partial request - skip.\n");
+ if (cnt < sizeof(*req)) {
+ free(req);
+ ERROR("umad2sim_read: sim header incomplete - skip.\n");
+ umad->status = EAGAIN;
+ return umad_size();
+ }
+
+ if (cnt != sizeof(*req) + req->length) {
+ free(req);
+ ERROR("umad2sim_read: partial request - got %d length "
+ "in sim header %d - skip.\n",
+ cnt, sizeof(*req) + req->length);
umad->status = EAGAIN;
return umad_size();
}
- mgmt_class = mad_get_field(req.mad, 0, IB_MAD_MGMTCLASS_F);
+ mgmt_class = mad_get_field(req->mad, 0, IB_MAD_MGMTCLASS_F);
DEBUG("umad2sim_read: mad: method=%x, response=%x, mgmtclass=%x, "
"attrid=%x, attrmod=%x\n",
- mad_get_field(req.mad, 0, IB_MAD_METHOD_F),
- mad_get_field(req.mad, 0, IB_MAD_RESPONSE_F),
+ mad_get_field(req->mad, 0, IB_MAD_METHOD_F),
+ mad_get_field(req->mad, 0, IB_MAD_RESPONSE_F),
mgmt_class,
- mad_get_field(req.mad, 0, IB_MAD_ATTRID_F),
- mad_get_field(req.mad, 0, IB_MAD_ATTRMOD_F)
+ mad_get_field(req->mad, 0, IB_MAD_ATTRID_F),
+ mad_get_field(req->mad, 0, IB_MAD_ATTRMOD_F)
);
if (mgmt_class >= arrsize(dev->agent_idx)) {
@@ -407,23 +424,24 @@ static ssize_t umad2sim_read(struct umad2sim_dev *dev, void *buf, size_t count)
mgmt_class = 0;
}
+ cnt -= sizeof(*req);
umad->agent_id = dev->agent_idx[mgmt_class];
- umad->status = ntohl(req.status);
+ umad->status = ntohl(req->status);
umad->timeout_ms = 0;
umad->retries = 0;
- umad->length = umad_size() + sizeof(req.mad);
+ umad->length = umad_size() + cnt;
- umad->addr.qpn = req.sqp;
+ umad->addr.qpn = req->sqp;
umad->addr.qkey = 0; // agent->qkey;
- umad->addr.lid = req.slid;
+ umad->addr.lid = req->slid;
umad->addr.sl = 0; // agent->sl;
umad->addr.path_bits = 0;
umad->addr.grh_present = 0;
- cnt -= sizeof(req) - sizeof(req.mad);
if (cnt > count - umad_size())
cnt = count - umad_size();
- memcpy(umad_get_mad(umad), req.mad, cnt);
+ memcpy(umad_get_mad(umad), req->mad, cnt);
+ free(req);
return cnt + umad_size();
}
@@ -431,9 +449,9 @@ static ssize_t umad2sim_read(struct umad2sim_dev *dev, void *buf, size_t count)
static ssize_t umad2sim_write(struct umad2sim_dev *dev,
const void *buf, size_t count)
{
- struct sim_request req;
+ struct sim_request *req;
ib_user_mad_t *umad = (ib_user_mad_t *) buf;
- int cnt;
+ int cnt, ocnt;
#ifdef SIMULATE_SEND_ERRORS
{ static int err_count;
@@ -464,25 +482,33 @@ static ssize_t umad2sim_write(struct umad2sim_dev *dev,
mad_get_field(umad_get_mad(umad), 0, IB_MAD_ATTRMOD_F)
);
- req.dlid = umad->addr.lid;
- req.slid = req.dlid == 0xffff ? 0xffff : 0; /* 0 - means auto
+ cnt = count - umad_size();
+ if (cnt > MAD_BLOCK_SIZE)
+ cnt = MAD_BLOCK_SIZE;
+ req = malloc(sizeof(*req) + cnt);
+ if (!req) {
+ ERROR("umad2sim_write: no mem for sim req: %m");
+ return -1;
+ }
+
+ req->dlid = umad->addr.lid;
+ req->slid = req->dlid == 0xffff ? 0xffff : 0; /* 0 - means auto
(supported by ibsim) */ ;
- req.dqp = umad->addr.qpn;
- req.sqp = htonl(dev->agents[umad->agent_id].qpn);
- req.status = 0;
- req.context = 0;
+ req->dqp = umad->addr.qpn;
+ req->sqp = htonl(dev->agents[umad->agent_id].qpn);
+ req->status = 0;
+ req->length = cnt;
+ req->context = 0;
- cnt = count - umad_size();
- if (cnt > sizeof(req.mad))
- cnt = sizeof(req.mad);
- memcpy(req.mad, umad_get_mad(umad), cnt);
+ memcpy(req->mad, umad_get_mad(umad), cnt);
- cnt = write(dev->sim_client.fd_pktout, (void *)&req, sizeof(req));
- if (cnt < 0) {
+ ocnt = write(dev->sim_client.fd_pktout, req, sizeof(*req) + cnt);
+ free(req);
+ if (ocnt < 0) {
ERROR("umad2sim_write: cannot write\n");
return -1;
}
- if (cnt < sizeof(req)) {
+ if (ocnt < sizeof(*req) + cnt) {
ERROR("umad2sim_write: partial write\n");
}
More information about the general
mailing list