|
@@ -52,19 +52,6 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event,
|
|
|
struct sctp_association *asoc);
|
|
|
static void sctp_ulpevent_release_data(struct sctp_ulpevent *event);
|
|
|
|
|
|
-/* Stub skb destructor. */
|
|
|
-static void sctp_stub_rfree(struct sk_buff *skb)
|
|
|
-{
|
|
|
-/* WARNING: This function is just a warning not to use the
|
|
|
- * skb destructor. If the skb is shared, we may get the destructor
|
|
|
- * callback on some processor that does not own the sock_lock. This
|
|
|
- * was occuring with PACKET socket applications that were monitoring
|
|
|
- * our skbs. We can't take the sock_lock, because we can't risk
|
|
|
- * recursing if we do really own the sock lock. Instead, do all
|
|
|
- * of our rwnd manipulation while we own the sock_lock outright.
|
|
|
- */
|
|
|
-}
|
|
|
-
|
|
|
/* Initialize an ULP event from an given skb. */
|
|
|
SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
|
|
|
{
|
|
@@ -111,15 +98,19 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
|
|
|
*/
|
|
|
sctp_association_hold((struct sctp_association *)asoc);
|
|
|
skb = sctp_event2skb(event);
|
|
|
- skb->sk = asoc->base.sk;
|
|
|
event->asoc = (struct sctp_association *)asoc;
|
|
|
- skb->destructor = sctp_stub_rfree;
|
|
|
+ atomic_add(skb->truesize, &event->asoc->rmem_alloc);
|
|
|
+ skb_set_owner_r(skb, asoc->base.sk);
|
|
|
}
|
|
|
|
|
|
/* A simple destructor to give up the reference to the association. */
|
|
|
static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
|
|
|
{
|
|
|
- sctp_association_put(event->asoc);
|
|
|
+ struct sctp_association *asoc = event->asoc;
|
|
|
+ struct sk_buff *skb = sctp_event2skb(event);
|
|
|
+
|
|
|
+ atomic_sub(skb->truesize, &asoc->rmem_alloc);
|
|
|
+ sctp_association_put(asoc);
|
|
|
}
|
|
|
|
|
|
/* Create and initialize an SCTP_ASSOC_CHANGE event.
|
|
@@ -922,7 +913,6 @@ done:
|
|
|
/* Free a ulpevent that has an owner. It includes releasing the reference
|
|
|
* to the owner, updating the rwnd in case of a DATA event and freeing the
|
|
|
* skb.
|
|
|
- * See comments in sctp_stub_rfree().
|
|
|
*/
|
|
|
void sctp_ulpevent_free(struct sctp_ulpevent *event)
|
|
|
{
|