This patch makes changes to the tcp_read_sock API. It allows that
function
to put skb's on the async_wait_queue becuase when the actor has
returned to
tcp_read_sock it's only known that the DMA copy was scheduled, not
that is
completed. tcp_read_sock will call the skb's destructor and put the
skb on
the async_wait_queue to be free'd by iSCSI when it's sure that the DMA
copies have completed.
Signed-off-by: Supreeth Venkataraman <[EMAIL PROTECTED]>
---
include/net/sock.h | 7 ++++++-
include/net/tcp.h | 2 +-
net/ipv4/tcp.c | 8 +++++---
net/sunrpc/xprtsock.c | 2 +-
4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index fd8edc4..4e488fa 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1342,8 +1342,13 @@ static inline void sk_eat_skb(struct sock *sk,
struct sk_buff *skb, int copied_e
__skb_unlink(skb, &sk->sk_receive_queue);
if (!copied_early)
__kfree_skb(skb);
- else
+ else {
+ if (skb->destructor) {
+ skb->destructor(skb);
+ skb->destructor = NULL;
+ }
__skb_queue_tail(&sk->sk_async_wait_queue, skb);
+ }
}
#else
static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb,
int copied_early)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 396f85d..9109698 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -475,7 +475,7 @@ extern void tcp_get_info(struct sock *, struct
tcp_info *);
/* Read 'sendfile()'-style from a TCP socket */
typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
- unsigned int, size_t);
+ unsigned int, size_t, int *copied_early);
extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
sk_read_actor_t recv_actor);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8d67edb..09058dd 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1049,6 +1049,7 @@ int tcp_read_sock(struct sock *sk,
read_descriptor_t *desc,
u32 seq = tp->copied_seq;
u32 offset;
int copied = 0;
+ int copied_early = 0;
if (sk->sk_state == TCP_LISTEN)
return -ENOTCONN;
@@ -1065,7 +1066,8 @@ int tcp_read_sock(struct sock *sk,
read_descriptor_t *desc,
if (!len)
break;
}
- used = recv_actor(desc, skb, offset, len);
+
+ used = recv_actor(desc, skb, offset, len,
&copied_early);
if (used < 0) {
if (!copied)
copied = used;
@@ -1079,11 +1081,11 @@ int tcp_read_sock(struct sock *sk,
read_descriptor_t *desc,
break;
}
if (tcp_hdr(skb)->fin) {
- sk_eat_skb(sk, skb, 0);
+ sk_eat_skb(sk, skb, copied_early);
++seq;
break;
}
- sk_eat_skb(sk, skb, 0);
+ sk_eat_skb(sk, skb, copied_early);
if (!desc->count)
break;
}
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 2f630a5..0087cfd 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1015,7 +1015,7 @@ static inline void xs_tcp_read_discard(struct
sock_xprt *transport, struct xdr_s
xs_tcp_check_fraghdr(transport);
}
-static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct
sk_buff *skb, unsigned int offset, size_t len)
+static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct
sk_buff *skb, unsigned int offset, size_t len, int *copied_early)
{
struct rpc_xprt *xprt = rd_desc->arg.data;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt,
xprt);
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"open-iscsi" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---