aboutsummaryrefslogtreecommitdiffstats
path: root/net/rxrpc/skbuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rxrpc/skbuff.c')
-rw-r--r--net/rxrpc/skbuff.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/net/rxrpc/skbuff.c b/net/rxrpc/skbuff.c
index eee0cfd9ac8c..06c51d4b622d 100644
--- a/net/rxrpc/skbuff.c
+++ b/net/rxrpc/skbuff.c
@@ -98,11 +98,39 @@ static void rxrpc_hard_ACK_data(struct rxrpc_call *call,
98 spin_unlock_bh(&call->lock); 98 spin_unlock_bh(&call->lock);
99} 99}
100 100
101/**
102 * rxrpc_kernel_data_consumed - Record consumption of data message
103 * @call: The call to which the message pertains.
104 * @skb: Message holding data
105 *
106 * Record the consumption of a data message and generate an ACK if appropriate.
107 * The call state is shifted if this was the final packet. The caller must be
108 * in process context with no spinlocks held.
109 *
110 * TODO: Actually generate the ACK here rather than punting this to the
111 * workqueue.
112 */
113void rxrpc_kernel_data_consumed(struct rxrpc_call *call, struct sk_buff *skb)
114{
115 struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
116
117 _enter("%d,%p{%u}", call->debug_id, skb, sp->hdr.seq);
118
119 ASSERTCMP(sp->call, ==, call);
120 ASSERTCMP(sp->hdr.type, ==, RXRPC_PACKET_TYPE_DATA);
121
122 /* TODO: Fix the sequence number tracking */
123 ASSERTCMP(sp->hdr.seq, >=, call->rx_data_recv);
124 ASSERTCMP(sp->hdr.seq, <=, call->rx_data_recv + 1);
125 ASSERTCMP(sp->hdr.seq, >, call->rx_data_eaten);
126
127 call->rx_data_recv = sp->hdr.seq;
128 rxrpc_hard_ACK_data(call, sp);
129}
130EXPORT_SYMBOL(rxrpc_kernel_data_consumed);
131
101/* 132/*
102 * destroy a packet that has an RxRPC control buffer 133 * Destroy a packet that has an RxRPC control buffer
103 * - advance the hard-ACK state of the parent call (done here in case something
104 * in the kernel bypasses recvmsg() and steals the packet directly off of the
105 * socket receive queue)
106 */ 134 */
107void rxrpc_packet_destructor(struct sk_buff *skb) 135void rxrpc_packet_destructor(struct sk_buff *skb)
108{ 136{
@@ -112,9 +140,8 @@ void rxrpc_packet_destructor(struct sk_buff *skb)
112 _enter("%p{%p}", skb, call); 140 _enter("%p{%p}", skb, call);
113 141
114 if (call) { 142 if (call) {
115 /* send the final ACK on a client call */ 143 if (atomic_dec_return(&call->skb_count) < 0)
116 if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA) 144 BUG();
117 rxrpc_hard_ACK_data(call, sp);
118 rxrpc_put_call(call); 145 rxrpc_put_call(call);
119 sp->call = NULL; 146 sp->call = NULL;
120 } 147 }