struct rx_srcavail_state {
/* Advertised buffer stuff */
u32 mseq;
- u32 used;
u32 reported;
u32 len;
u32 rkey;
u32 bytes_completed);
int sdp_handle_rdma_read_cqe(struct sdp_sock *ssk);
int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, struct sk_buff *skb,
- unsigned long *used);
+ unsigned long *used, u32 offset);
int sdp_post_rdma_rd_compl(struct sock *sk,
- struct rx_srcavail_state *rx_sa);
+ struct rx_srcavail_state *rx_sa, u32 offset);
int sdp_post_sendsm(struct sock *sk);
void srcavail_cancel_timeout(struct work_struct *work);
void sdp_abort_srcavail(struct sock *sk);
if (!skb)
break;
+ offset = *seq - SDP_SKB_CB(skb)->seq;
avail_bytes_count = 0;
h = (struct sdp_bsdh *)skb_transport_header(skb);
sdp_dbg_data(sk, "Ignoring src avail "
"due to SrcAvailCancel\n");
sdp_post_sendsm(sk);
- if (rx_sa->used < skb->len) {
+ if (offset < skb->len) {
sdp_abort_rx_srcavail(sk, skb);
sdp_prf(sk, skb, "Converted SA to DATA");
goto sdp_mid_data;
}
/* if has payload - handle as if MID_DATA */
- if (rx_sa->used < skb->len) {
+ if (offset < skb->len) {
sdp_dbg_data(sk, "SrcAvail has "
"payload: %d/%d\n",
- rx_sa->used,
+ offset,
skb->len);
avail_bytes_count = skb->len;
} else {
sdp_dbg_data(sk, "Finished payload. "
"RDMAing: %d/%d\n",
- rx_sa->used, rx_sa->len);
+ offset, rx_sa->len);
if (flags & MSG_PEEK) {
+ u32 real_offset =
+ ssk->copied_seq -
+ SDP_SKB_CB(skb)->seq;
sdp_dbg_data(sk, "Peek on RDMA data - "
"fallback to BCopy\n");
sdp_abort_rx_srcavail(sk, skb);
sdp_post_sendsm(sk);
rx_sa = NULL;
+ if (real_offset >= skb->len)
+ goto force_skb_cleanup;
} else {
avail_bytes_count = rx_sa->len;
}
break;
}
- offset = *seq - SDP_SKB_CB(skb)->seq;
if (offset < avail_bytes_count)
goto found_ok_skb;
}
}
if (!(flags & MSG_TRUNC)) {
- if (rx_sa && rx_sa->used >= skb->len) {
+ if (rx_sa && offset >= skb->len) {
/* No more payload - start rdma copy */
sdp_dbg_data(sk, "RDMA copy of %lx bytes\n", used);
- err = sdp_rdma_to_iovec(sk, msg->msg_iov, skb, &used);
+ err = sdp_rdma_to_iovec(sk, msg->msg_iov, skb,
+ &used, offset);
sdp_dbg_data(sk, "used = %lx bytes\n", used);
if (err == -EAGAIN) {
sdp_dbg_data(sk, "RDMA Read aborted\n");
/* TODO: skip header? */
msg->msg_iov, used);
if (rx_sa && !(flags & MSG_PEEK)) {
- rx_sa->used += used;
rx_sa->reported += used;
}
}
copied += used;
len -= used;
*seq += used;
-
+ offset = *seq - SDP_SKB_CB(skb)->seq;
sdp_dbg_data(sk, "done copied %d target %d\n", copied, target);
sdp_do_posts(sdp_sk(sk));
if (rx_sa && !(flags & MSG_PEEK)) {
- rc = sdp_post_rdma_rd_compl(sk, rx_sa);
+ rc = sdp_post_rdma_rd_compl(sk, rx_sa, offset);
BUG_ON(rc);
}
- if (!rx_sa && used + offset < skb->len)
+ if (!rx_sa && offset < skb->len)
continue;
- if (rx_sa && rx_sa->used < rx_sa->len)
+ if (rx_sa && offset < rx_sa->len)
continue;
offset = 0;
rx_sa = NULL;
}
-
+force_skb_cleanup:
sdp_dbg_data(sk, "unlinking skb %p\n", skb);
skb_unlink(skb, &sk->sk_receive_queue);
__kfree_skb(skb);
}
int sdp_post_rdma_rd_compl(struct sock *sk,
- struct rx_srcavail_state *rx_sa)
+ struct rx_srcavail_state *rx_sa, u32 offset)
{
struct sk_buff *skb;
- int copied = rx_sa->used - rx_sa->reported;
+ int copied = offset - rx_sa->reported;
- if (rx_sa->used <= rx_sa->reported)
+ if (offset <= rx_sa->reported)
return 0;
skb = sdp_alloc_skb_rdmardcompl(sk, copied, 0);
*_umem = NULL;
}
-static int sdp_post_rdma_read(struct sock *sk, struct rx_srcavail_state *rx_sa)
+static int sdp_post_rdma_read(struct sock *sk, struct rx_srcavail_state *rx_sa,
+ u32 offset)
{
struct sdp_sock *ssk = sdp_sk(sk);
struct ib_send_wr *bad_wr;
sge.length = rx_sa->umem->length;
sge.lkey = rx_sa->fmr->fmr->lkey;
- wr.wr.rdma.remote_addr = rx_sa->vaddr + rx_sa->used;
+ wr.wr.rdma.remote_addr = rx_sa->vaddr + offset;
wr.num_sge = 1;
wr.sg_list = &sge;
rx_sa->busy++;
}
int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, struct sk_buff *skb,
- unsigned long *used)
+ unsigned long *used, u32 offset)
{
struct sdp_sock *ssk = sdp_sk(sk);
struct rx_srcavail_state *rx_sa = RX_SRCAVAIL_STATE(skb);
goto err_alloc_fmr;
}
- rc = sdp_post_rdma_read(sk, rx_sa);
+ rc = sdp_post_rdma_read(sk, rx_sa, offset);
if (unlikely(rc)) {
sdp_warn(sk, "ib_post_send failed with status %d.\n", rc);
sdp_set_error(&ssk->isk.sk, -ECONNRESET);
copied = rx_sa->umem->length;
sdp_update_iov_used(sk, iov, copied);
- rx_sa->used += copied;
atomic_add(copied, &ssk->rcv_nxt);
*used = copied;