c->state.max_receive_size = SMB_DIRECT_IO_MAX_DATA;
c->state.max_fragmented_size = 1048576;
c->state.max_read_write_size = 0;
- c->state.receive_credit_max = 2;
+ c->state.receive_credit_max = 128;//255;
c->state.send_credit_target = 255;
c->state.keep_alive_internal = 5;
smb_set_close_on_exec(c->ibv.comp_channel->fd);
set_blocking(c->ibv.comp_channel->fd, false);
- c->ibv.init_attr.cap.max_send_wr = 2;
- c->ibv.init_attr.cap.max_recv_wr = 2;
+ c->ibv.init_attr.cap.max_send_wr = c->state.send_credit_target; // more for RDMA READ/WRITE??
+ c->ibv.init_attr.cap.max_recv_wr = c->state.receive_credit_max; // more for RDMA READ/WRITE??
c->ibv.init_attr.cap.max_recv_sge = 2;
c->ibv.init_attr.cap.max_send_sge = 2;
c->ibv.init_attr.qp_type = IBV_QPT_RC;
return c;
}
+static void smb_direct_connection_debug_credits(struct smb_direct_connection *c,
+ const char *location, const char *func)
+{
+ DEBUG(0,("%s:%s: CREDITS: RMAX[%u] RTARGET[%u] R[%u] STARGET[%u] S[%u]\n",
+ location, func,
+ c->state.receive_credit_max,
+ c->state.receive_credit_target,
+ c->state.receive_credits,
+ c->state.send_credit_target,
+ c->state.send_credits));
+}
+
static int smb_direct_connection_destructor(struct smb_direct_connection *c)
{
TALLOC_FREE(c->sock.fde);
int ret;
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+smb_direct_connection_debug_credits(c, __location__, __func__);
if (c->r2s.idle == NULL) {
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return 0;
int ret;
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+smb_direct_connection_debug_credits(c, __location__, __func__);
if (c->s2r.ready == NULL) {
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return 0;
next = io->next;
if (c->state.send_credits == 0) {
+smb_direct_connection_debug_credits(c, __location__, __func__);
break;
}
granted -= c->state.receive_credits;
granted = MIN(granted, c->state.receive_credit_target);
c->state.receive_credits += granted;
+smb_direct_connection_debug_credits(c, __location__, __func__);
+
// if (c->state.receive_credits == 0) {
// granted = 1;
// c->state.receive_credits += granted;
}
DLIST_REMOVE(c->s2r.ready, io);
DLIST_ADD_END(posted, io);
+ DEBUG(0,("%s:%s: POST SEND[%p] data_length[%u] remaining_length[%u]\n",
+ __location__, __FUNCTION__, io,
+ (unsigned)io->data_length, (unsigned)io->remaining_length));
}
last = DLIST_TAIL(posted);
struct smb_direct_io *io = NULL;
int ret;
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: KEEP posted[%p] ready[%p] idle[%p]\n",
+ __location__, __func__, ));
if (c->s2r.posted != NULL) {
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
- return 0;
+// return 0;
}
if (c->s2r.ready != NULL) {
}
static int smb_direct_connection_setup_readv(struct smb_direct_connection *c)
{
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_READABLE on\n", __location__, __func__));
TEVENT_FD_READABLE(c->sock.fde);
// TODO: immediate_event?? may skips a syscall.
return 0;
static int smb_direct_connection_setup_writev(struct smb_direct_connection *c)
{
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_WRITEABLE on\n", __location__, __func__));
TEVENT_FD_WRITEABLE(c->sock.fde);
// TODO: immediate_event?? may skips a syscall.
return 0;
struct ibv_wc wc;
int ret;
uint16_t credits_requested;
- uint16_t credits_granted;
+ uint32_t credits_granted;
uint16_t flags;
uint32_t data_offset;
struct smb_direct_io *io = NULL;
switch (wc.opcode) {
case IBV_WC_SEND:
- DEBUG(0,("%s:%s: GOT SEND[%p] ret[%d] errno[%d]\n",
- __location__, __FUNCTION__, io, ret, errno));
+ DEBUG(0,("%s:%s: GOT SEND[%p] data_length[%u] remaining_length[%u] ret[%d] errno[%d]\n",
+ __location__, __FUNCTION__, io,
+ (unsigned)io->data_length, (unsigned)io->remaining_length, ret, errno));
DLIST_REMOVE(c->s2r.posted, io);
DLIST_ADD_END(c->s2r.idle, io);
case IBV_WC_RECV:
DEBUG(0,("%s:%s: GOT RECV[%p] ret[%d] errno[%d]\n",
__location__, __FUNCTION__, io, ret, errno));
- if (wc.byte_len >= c->state.max_receive_size) {
+ if (wc.byte_len > c->state.max_receive_size) {
status = NT_STATUS_INVALID_NETWORK_RESPONSE;
- DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
- __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+ DEBUG(0,("%s:%s: wc.byte_len[%u/0x%x] max_receive_size[%u/0x%x] ret[%d] errno[%d] status[%s]\n",
+ __location__, __FUNCTION__,
+ (unsigned)wc.byte_len,
+ (unsigned)wc.byte_len,
+ (unsigned)c->state.max_receive_size,
+ (unsigned)c->state.max_receive_size,
+ ret, errno, nt_errstr(status)));
smb_direct_connection_disconnect(c, status);
return;
}
return;
}
credits_granted = SVAL(io->smbd_hdr, 0x02);
- if (credits_granted == 0) {
- status = NT_STATUS_INVALID_NETWORK_RESPONSE;
- DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
- __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
- smb_direct_connection_disconnect(c, status);
- return;
- }
flags = SVAL(io->smbd_hdr, 0x04);
io->remaining_length = IVAL(io->smbd_hdr, 0x08);
data_offset = IVAL(io->smbd_hdr, 0x0C);
c->state.receive_credits -= 1;
c->state.receive_credit_target = credits_requested;
- c->state.send_credits += credits_granted;
+ credits_granted += c->state.send_credits;
+ if (credits_granted > c->state.send_credit_target) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
+ __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+ smb_direct_connection_disconnect(c, status);
+ return;
+ }
+ c->state.send_credits = credits_granted;
+
+smb_direct_connection_debug_credits(c, __location__, __func__);
if (data_offset == 0) {
if (wc.byte_len != 0x14) {
status = NT_STATUS_INVALID_NETWORK_RESPONSE;
}
return;
} else if (data_offset == 0x18) {
- if (io->data_length >= (c->state.max_receive_size - data_offset)) {
+ if (io->data_length > (c->state.max_receive_size - data_offset)) {
status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ DEBUG(0,("%s:%s: io->data_length[%u/0x%x] max_receive_size-data_offset[%u/0x%x] ret[%d] errno[%d] status[%s]\n",
+ __location__, __FUNCTION__,
+ (unsigned)io->data_length,
+ (unsigned)io->data_length,
+ (unsigned)c->state.max_receive_size - data_offset,
+ (unsigned)c->state.max_receive_size - data_offset,
+ ret, errno, nt_errstr(status)));
DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
__location__, __FUNCTION__, ret, errno, nt_errstr(status)));
smb_direct_connection_disconnect(c, status);
io->iov[0].iov_base = io->data;
io->iov[0].iov_len = io->data_length;
io->iov_count = 1;
+ DEBUG(0,("%s:%s: CONTINUE[%p] io->data_length[%u] io->remaining_length[%u]\n",
+ __location__, __func__, io,
+ (unsigned)io->data_length,
+ (unsigned)io->remaining_length));
} else {
uint64_t total_length = io->data_length + io->remaining_length;
io->iov[1].iov_base = io->data;
io->iov[1].iov_len = io->data_length;
io->iov_count = 2;
+ DEBUG(0,("%s:%s: START[%p] total_length[%u] io->data_length[%u] io->remaining_length[%u]\n",
+ __location__, __func__, io, (unsigned)total_length,
+ (unsigned)io->data_length,
+ (unsigned)io->remaining_length));
+
+ c->r2s.remaining_length = io->remaining_length;;
}
if (c->state.receive_credits == 0) {
int ret;
bool ok;
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
do_write:
if (fde_flags & TEVENT_FD_WRITE) {
if (c->r2s.out != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->r2s.out;
} else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->r2s.ready;
if (io != NULL) {
DLIST_REMOVE(c->r2s.ready, io);
if (io != NULL) {
ssize_t sret;
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
sret = writev(c->sock.fd, io->iov, io->iov_count);
if (sret == -1) {
if (errno == EAGAIN) { // and more...
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_NOT_WRITEABLE writev...\n", __location__, __func__));
TEVENT_FD_WRITEABLE(c->sock.fde);
goto done_write;
}
if (io->iov_count == 0) {
c->r2s.out = NULL;
DLIST_ADD_END(c->r2s.idle, io);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
goto do_write;
}
} else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_NOT_WRITEABLE\n", __location__, __func__));
TEVENT_FD_NOT_WRITEABLE(c->sock.fde);
}
}
done_write:
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
ret = smb_direct_connection_post_recv(c);
if (ret != 0) {
status = map_nt_error_from_unix_common(errno);
do_read:
if (fde_flags & TEVENT_FD_READ) {
if (c->s2r.in != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->s2r.in;
} else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
io = c->s2r.idle;
if (io != NULL) {
DLIST_REMOVE(c->s2r.idle, io);
c->s2r.in = io;
if (c->s2r.remaining_length > 0) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
/*
* We need to continue to get
* the incomplete packet.
io->iov[0].iov_base = io->data;
io->iov[0].iov_len = io->data_length;
io->iov_count = 1;
+ DEBUG(0,("%s:%s: CONTINUE[%p] io->data_length[%u] io->remaining_length[%u]\n",
+ __location__, __func__, io,
+ (unsigned)io->data_length,
+ (unsigned)io->remaining_length));
} else {
- DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+ DEBUG(0,("%s:%s: WAIT[%p] for NBT\n", __location__, __func__, io));
/*
* For a new packet we need to get the length
* first.
if (io != NULL) {
ssize_t sret;
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
sret = readv(c->sock.fd, io->iov, io->iov_count);
if (sret == -1) {
if (errno == EAGAIN) { // and more...
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_READABLE...\n", __location__, __func__));
TEVENT_FD_READABLE(c->sock.fde);
goto done_read;
}
if (io->iov_count == 0) {
if (io->data_length != 0) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: FINISH[%p] io->data_length[%u] io->remaining_length[%u]\n",
+ __location__, __func__, io, (unsigned)io->data_length, (unsigned)io->remaining_length));
/*
* We managed to read the whole fragment
* which is ready to be posted into the
goto do_read;
}
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
c->s2r.remaining_length = smb_len_tcp(io->nbt_hdr);
if (c->s2r.remaining_length > c->state.max_fragmented_size) { //correct direction
status = NT_STATUS_INVALID_BUFFER_SIZE;
c->s2r.remaining_length);
io->remaining_length = c->s2r.remaining_length;
io->remaining_length -= io->data_length;
- c->s2r.remaining_length = io->remaining_length;
io->iov = io->_iov_array;
io->iov[0].iov_base = io->data;
io->iov[0].iov_len = io->data_length;
io->iov_count = 1;
+ DEBUG(0,("%s:%s: AFTER[%p] total[%u] io->data_length[%u] io->remaining_length[%u]\n",
+ __location__, __func__, io, (unsigned)c->s2r.remaining_length,
+ (unsigned)io->data_length,
+ (unsigned)io->remaining_length));
+ c->s2r.remaining_length = io->remaining_length;
/*
* try to read the reset immediately.
*/
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
goto do_read;
}
} else {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+DEBUG(0,("%s:%s: TEVENT_FD_NOT_READABLE...\n", __location__, __func__));
TEVENT_FD_NOT_READABLE(c->sock.fde);
}
}
done_read:
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
ret = smb_direct_connection_post_send(c);
if (ret != 0) {
status = map_nt_error_from_unix_common(errno);
{
uint16_t sock_fde_flags = TEVENT_FD_READ;
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
if (c->r2s.out != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
sock_fde_flags |= TEVENT_FD_WRITE;
}
TALLOC_FREE(c->sock.fde);
TALLOC_FREE(c->ibv.fde_channel);
TALLOC_FREE(c->rdma.fde_channel);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
}
if (tevent_fd_get_flags(c->rdma.fde_channel) == 0) {
TALLOC_FREE(c->sock.fde);
TALLOC_FREE(c->ibv.fde_channel);
TALLOC_FREE(c->rdma.fde_channel);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
}
if (ev == NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
c->last_ev = NULL;
TALLOC_FREE(c->sock.fde);
TALLOC_FREE(c->ibv.fde_channel);
}
if (ev == c->last_ev) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return NT_STATUS_OK;
}
if (c->last_ev != NULL) {
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
+//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return NT_STATUS_INVALID_PARAMETER_MIX;
}