Commit 2766297c authored by Sridhar Samudrala's avatar Sridhar Samudrala

[SCTP] Reduce the size of struct sctp_ulpevent so that it fits in

       skb->cb even on 64-bit systems. 

Removed the redundant 'asoc' field in struct sctp_ulpevent and
instead use sinfo_assoc_id which is present within the other field
'sndrcvinfo'. This makes the size of struct sctp_ulpevent to be less
than the size of skb->cb[](48 bytes) even on 64-bit systems.
parent 845ddb44
...@@ -54,7 +54,6 @@ ...@@ -54,7 +54,6 @@
* growing this structure as it is at the maximum limit now. * growing this structure as it is at the maximum limit now.
*/ */
struct sctp_ulpevent { struct sctp_ulpevent {
struct sctp_association *asoc;
struct sctp_sndrcvinfo sndrcvinfo; struct sctp_sndrcvinfo sndrcvinfo;
int msg_flags; int msg_flags;
int iif; int iif;
......
...@@ -662,18 +662,20 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, ...@@ -662,18 +662,20 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
if (msgname) { if (msgname) {
union sctp_addr *addr; union sctp_addr *addr;
struct sctp_association *asoc;
asoc = event->sndrcvinfo.sinfo_assoc_id;
sctp_inet6_msgname(msgname, addrlen); sctp_inet6_msgname(msgname, addrlen);
sin6 = (struct sockaddr_in6 *)msgname; sin6 = (struct sockaddr_in6 *)msgname;
sin6->sin6_port = htons(event->asoc->peer.port); sin6->sin6_port = htons(asoc->peer.port);
addr = &event->asoc->peer.primary_addr; addr = &asoc->peer.primary_addr;
/* Note: If we go to a common v6 format, this code /* Note: If we go to a common v6 format, this code
* will change. * will change.
*/ */
/* Map ipv4 address into v4-mapped-on-v6 address. */ /* Map ipv4 address into v4-mapped-on-v6 address. */
if (sctp_sk(event->asoc->base.sk)->v4mapped && if (sctp_sk(asoc->base.sk)->v4mapped &&
AF_INET == addr->sa.sa_family) { AF_INET == addr->sa.sa_family) {
sctp_v4_map_v6((union sctp_addr *)sin6); sctp_v4_map_v6((union sctp_addr *)sin6);
sin6->sin6_addr.s6_addr32[3] = sin6->sin6_addr.s6_addr32[3] =
...@@ -681,7 +683,7 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, ...@@ -681,7 +683,7 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
return; return;
} }
sin6from = &event->asoc->peer.primary_addr.v6; sin6from = &asoc->peer.primary_addr.v6;
ipv6_addr_copy(&sin6->sin6_addr, &sin6from->sin6_addr); ipv6_addr_copy(&sin6->sin6_addr, &sin6from->sin6_addr);
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id = sin6from->sin6_scope_id; sin6->sin6_scope_id = sin6from->sin6_scope_id;
......
...@@ -691,10 +691,13 @@ static void sctp_inet_event_msgname(struct sctp_ulpevent *event, char *msgname, ...@@ -691,10 +691,13 @@ static void sctp_inet_event_msgname(struct sctp_ulpevent *event, char *msgname,
struct sockaddr_in *sin, *sinfrom; struct sockaddr_in *sin, *sinfrom;
if (msgname) { if (msgname) {
struct sctp_association *asoc;
asoc = event->sndrcvinfo.sinfo_assoc_id;
sctp_inet_msgname(msgname, addr_len); sctp_inet_msgname(msgname, addr_len);
sin = (struct sockaddr_in *)msgname; sin = (struct sockaddr_in *)msgname;
sinfrom = &event->asoc->peer.primary_addr.v4; sinfrom = &asoc->peer.primary_addr.v4;
sin->sin_port = htons(event->asoc->peer.port); sin->sin_port = htons(asoc->peer.port);
sin->sin_addr.s_addr = sinfrom->sin_addr.s_addr; sin->sin_addr.s_addr = sinfrom->sin_addr.s_addr;
} }
} }
......
...@@ -1347,7 +1347,8 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, ...@@ -1347,7 +1347,8 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk,
* rwnd by that amount. If all the data in the skb is read, * rwnd by that amount. If all the data in the skb is read,
* rwnd is updated when the event is freed. * rwnd is updated when the event is freed.
*/ */
sctp_assoc_rwnd_increase(event->asoc, copied); sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id,
copied);
goto out; goto out;
} else if ((event->msg_flags & MSG_NOTIFICATION) || } else if ((event->msg_flags & MSG_NOTIFICATION) ||
(event->msg_flags & MSG_EOR)) (event->msg_flags & MSG_EOR))
...@@ -4233,7 +4234,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, ...@@ -4233,7 +4234,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
*/ */
sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
event = sctp_skb2event(skb); event = sctp_skb2event(skb);
if (event->asoc == assoc) { if (event->sndrcvinfo.sinfo_assoc_id == assoc) {
__skb_unlink(skb, skb->list); __skb_unlink(skb, skb->list);
__skb_queue_tail(&newsk->sk_receive_queue, skb); __skb_queue_tail(&newsk->sk_receive_queue, skb);
} }
...@@ -4262,7 +4263,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, ...@@ -4262,7 +4263,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
*/ */
sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
event = sctp_skb2event(skb); event = sctp_skb2event(skb);
if (event->asoc == assoc) { if (event->sndrcvinfo.sinfo_assoc_id == assoc) {
__skb_unlink(skb, skb->list); __skb_unlink(skb, skb->list);
__skb_queue_tail(queue, skb); __skb_queue_tail(queue, skb);
} }
......
...@@ -831,14 +831,14 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event, ...@@ -831,14 +831,14 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
sctp_association_hold((struct sctp_association *)asoc); sctp_association_hold((struct sctp_association *)asoc);
skb = sctp_event2skb(event); skb = sctp_event2skb(event);
skb->sk = asoc->base.sk; skb->sk = asoc->base.sk;
event->asoc = (struct sctp_association *)asoc; event->sndrcvinfo.sinfo_assoc_id = sctp_assoc2id(asoc);
skb->destructor = sctp_stub_rfree; skb->destructor = sctp_stub_rfree;
} }
/* A simple destructor to give up the reference to the association. */ /* A simple destructor to give up the reference to the association. */
static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
{ {
sctp_association_put(event->asoc); sctp_association_put(event->sndrcvinfo.sinfo_assoc_id);
} }
/* Do accounting for bytes received and hold a reference to the association /* Do accounting for bytes received and hold a reference to the association
...@@ -880,7 +880,8 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) ...@@ -880,7 +880,8 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
*/ */
skb = sctp_event2skb(event); skb = sctp_event2skb(event);
sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb)); sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id,
skb_headlen(skb));
/* Don't forget the fragments. */ /* Don't forget the fragments. */
for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment