aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-04-13 23:04:44 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-13 23:04:44 -0400
commitdfb6cbf693536937fc49a7c5822dd39ef9d1a8e5 (patch)
treec9cd81d9f5ddf626822d059e55f4c4691668de50
parentea019649c37b8aa0d1ac5727d122b2e8ed74f536 (diff)
parentfb586f25300f4587c7ebd097a604bf269b25bfa7 (diff)
Merge branch 'sctp-delayed-wakeups'
Marcelo Ricardo Leitner says: ==================== sctp: delay calls to sk_data_ready() as much as possible 1st patch is a preparation for the 2nd. The idea is to not call ->sk_data_ready() for every data chunk processed while processing packets but only once before releasing the socket. v2: patchset re-checked, small changelog fixes v3: on patch 2, make use of local vars to make it more readable ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/structs.h13
-rw-r--r--net/sctp/sm_sideeffect.c7
-rw-r--r--net/sctp/ulpqueue.c4
3 files changed, 16 insertions, 8 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 6df1ce7a411c..21cb11107e37 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -210,14 +210,15 @@ struct sctp_sock {
int user_frag;
__u32 autoclose;
- __u8 nodelay;
- __u8 disable_fragments;
- __u8 v4mapped;
- __u8 frag_interleave;
__u32 adaptation_ind;
__u32 pd_point;
- __u8 recvrcvinfo;
- __u8 recvnxtinfo;
+ __u16 nodelay:1,
+ disable_fragments:1,
+ v4mapped:1,
+ frag_interleave:1,
+ recvrcvinfo:1,
+ recvnxtinfo:1,
+ pending_data_ready:1;
atomic_t pd_mode;
/* Receive to here while partial delivery is in effect. */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 7fe56d0acabf..d06317de8730 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1222,6 +1222,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_cmd_seq_t *commands,
gfp_t gfp)
{
+ struct sock *sk = ep->base.sk;
+ struct sctp_sock *sp = sctp_sk(sk);
int error = 0;
int force;
sctp_cmd_t *cmd;
@@ -1742,6 +1744,11 @@ out:
error = sctp_outq_uncork(&asoc->outqueue, gfp);
} else if (local_cork)
error = sctp_outq_uncork(&asoc->outqueue, gfp);
+
+ if (sp->pending_data_ready) {
+ sk->sk_data_ready(sk);
+ sp->pending_data_ready = 0;
+ }
return error;
nomem:
error = -ENOMEM;
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index ce469d648ffb..72e5b3e41cdd 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -264,7 +264,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
sctp_ulpq_clear_pd(ulpq);
if (queue == &sk->sk_receive_queue)
- sk->sk_data_ready(sk);
+ sctp_sk(sk)->pending_data_ready = 1;
return 1;
out_free:
@@ -1140,5 +1140,5 @@ void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
/* If there is data waiting, send it up the socket now. */
if (sctp_ulpq_clear_pd(ulpq) || ev)
- sk->sk_data_ready(sk);
+ sctp_sk(sk)->pending_data_ready = 1;
}