struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
                                        const struct sctp_sndrcvinfo *sinfo,
                                        int len, const __u8 flags,
-                                       __u16 ssn);
+                                       __u16 ssn, gfp_t gfp);
 struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
                                  const __u32);
 struct sctp_chunk *sctp_make_sack(const struct sctp_association *);
 
 void  *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
                                 const struct sctp_association *,
-                                struct sock *);
+                                struct sock *, gfp_t gfp);
 void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
                     union sctp_addr *);
 const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
                                     __u16 sport, __u16 dport);
 struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
 sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *,
-                                       struct sctp_chunk *, int);
+                                      struct sctp_chunk *, int, gfp_t);
 sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *,
                                      struct sctp_chunk *);
-int sctp_packet_transmit(struct sctp_packet *);
+int sctp_packet_transmit(struct sctp_packet *, gfp_t);
 void sctp_packet_free(struct sctp_packet *);
 
 static inline int sctp_packet_empty(struct sctp_packet *packet)
 void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
 void sctp_outq_teardown(struct sctp_outq *);
 void sctp_outq_free(struct sctp_outq*);
-int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk);
+int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk, gfp_t);
 int sctp_outq_sack(struct sctp_outq *, struct sctp_chunk *);
 int sctp_outq_is_empty(const struct sctp_outq *);
 void sctp_outq_restart(struct sctp_outq *);
 void sctp_retransmit(struct sctp_outq *, struct sctp_transport *,
                     sctp_retransmit_reason_t);
 void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
-int sctp_outq_uncork(struct sctp_outq *);
+int sctp_outq_uncork(struct sctp_outq *, gfp_t gfp);
 /* Uncork and flush an outqueue.  */
 static inline void sctp_outq_cork(struct sctp_outq *q)
 {
 
 
                asoc->peer.sack_needed = 0;
 
-               sctp_outq_tail(&asoc->outqueue, sack);
+               sctp_outq_tail(&asoc->outqueue, sack, GFP_ATOMIC);
 
                /* Stop the SACK timer.  */
                timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
 
                                frag |= SCTP_DATA_SACK_IMM;
                }
 
-               chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
+               chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag,
+                                                0, GFP_KERNEL);
 
                if (!chunk) {
                        err = -ENOMEM;
                    (sinfo->sinfo_flags & SCTP_SACK_IMMEDIATELY))
                        frag |= SCTP_DATA_SACK_IMM;
 
-               chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
+               chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag,
+                                                0, GFP_KERNEL);
 
                if (!chunk) {
                        err = -ENOMEM;
 
                goto discard_release;
 
        /* Create an SCTP packet structure. */
-       chunk = sctp_chunkify(skb, asoc, sk);
+       chunk = sctp_chunkify(skb, asoc, sk, GFP_ATOMIC);
        if (!chunk)
                goto discard_release;
        SCTP_INPUT_CB(skb)->chunk = chunk;
 
  */
 sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
                                       struct sctp_chunk *chunk,
-                                      int one_packet)
+                                      int one_packet, gfp_t gfp)
 {
        sctp_xmit_t retval;
        int error = 0;
        switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) {
        case SCTP_XMIT_PMTU_FULL:
                if (!packet->has_cookie_echo) {
-                       error = sctp_packet_transmit(packet);
+                       error = sctp_packet_transmit(packet, gfp);
                        if (error < 0)
                                chunk->skb->sk->sk_err = -error;
 
  *
  * The return value is a normal kernel error return value.
  */
-int sctp_packet_transmit(struct sctp_packet *packet)
+int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
 {
        struct sctp_transport *tp = packet->transport;
        struct sctp_association *asoc = tp->asoc;
 
 
 static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
 
-static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout);
+static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp);
 
 /* Add data to the front of the queue. */
 static inline void sctp_outq_head_data(struct sctp_outq *q,
 }
 
 /* Put a new chunk in an sctp_outq.  */
-int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
+int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk, gfp_t gfp)
 {
        struct net *net = sock_net(q->asoc->base.sk);
        int error = 0;
                return error;
 
        if (!q->cork)
-               error = sctp_outq_flush(q, 0);
+               error = sctp_outq_flush(q, 0, gfp);
 
        return error;
 }
         * will be flushed at the end.
         */
        if (reason != SCTP_RTXR_FAST_RTX)
-               error = sctp_outq_flush(q, /* rtx_timeout */ 1);
+               error = sctp_outq_flush(q, /* rtx_timeout */ 1, GFP_ATOMIC);
 
        if (error)
                q->asoc->base.sk->sk_err = -error;
                                 * control chunks are already freed so there
                                 * is nothing we can do.
                                 */
-                               sctp_packet_transmit(pkt);
+                               sctp_packet_transmit(pkt, GFP_ATOMIC);
                                goto redo;
                        }
 
                        /* Send this packet.  */
-                       error = sctp_packet_transmit(pkt);
+                       error = sctp_packet_transmit(pkt, GFP_ATOMIC);
 
                        /* If we are retransmitting, we should only
                         * send a single packet.
 
                case SCTP_XMIT_RWND_FULL:
                        /* Send this packet. */
-                       error = sctp_packet_transmit(pkt);
+                       error = sctp_packet_transmit(pkt, GFP_ATOMIC);
 
                        /* Stop sending DATA as there is no more room
                         * at the receiver.
 
                case SCTP_XMIT_DELAY:
                        /* Send this packet. */
-                       error = sctp_packet_transmit(pkt);
+                       error = sctp_packet_transmit(pkt, GFP_ATOMIC);
 
                        /* Stop sending DATA because of nagle delay. */
                        done = 1;
 }
 
 /* Cork the outqueue so queued chunks are really queued. */
-int sctp_outq_uncork(struct sctp_outq *q)
+int sctp_outq_uncork(struct sctp_outq *q, gfp_t gfp)
 {
        if (q->cork)
                q->cork = 0;
 
-       return sctp_outq_flush(q, 0);
+       return sctp_outq_flush(q, 0, gfp);
 }
 
 
  * locking concerns must be made.  Today we use the sock lock to protect
  * this function.
  */
-static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
+static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
 {
        struct sctp_packet *packet;
        struct sctp_packet singleton;
                        sctp_packet_init(&singleton, transport, sport, dport);
                        sctp_packet_config(&singleton, vtag, 0);
                        sctp_packet_append_chunk(&singleton, chunk);
-                       error = sctp_packet_transmit(&singleton);
+                       error = sctp_packet_transmit(&singleton, gfp);
                        if (error < 0)
                                return error;
                        break;
                case SCTP_CID_ASCONF:
                case SCTP_CID_FWD_TSN:
                        status = sctp_packet_transmit_chunk(packet, chunk,
-                                                           one_packet);
+                                                           one_packet, gfp);
                        if (status  != SCTP_XMIT_OK) {
                                /* put the chunk back */
                                list_add(&chunk->list, &q->control_chunk_list);
                                 atomic_read(&chunk->skb->users) : -1);
 
                        /* Add the chunk to the packet.  */
-                       status = sctp_packet_transmit_chunk(packet, chunk, 0);
+                       status = sctp_packet_transmit_chunk(packet, chunk, 0, gfp);
 
                        switch (status) {
                        case SCTP_XMIT_PMTU_FULL:
                                                      send_ready);
                packet = &t->packet;
                if (!sctp_packet_empty(packet))
-                       error = sctp_packet_transmit(packet);
+                       error = sctp_packet_transmit(packet, gfp);
 
                /* Clear the burst limited state, if any */
                sctp_transport_burst_reset(t);
 
 #include <net/sctp/sm.h>
 
 static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
-                                           __u8 type, __u8 flags, int paylen);
+                                           __u8 type, __u8 flags, int paylen,
+                                           gfp_t gfp);
 static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
-                                        __u8 flags, int paylen);
+                                        __u8 flags, int paylen, gfp_t gfp);
 static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
-                                          __u8 type, __u8 flags, int paylen);
+                                          __u8 type, __u8 flags, int paylen,
+                                          gfp_t gfp);
 static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
                                        const struct sctp_association *asoc,
                                        const struct sctp_chunk *init_chunk,
         * PLEASE DO NOT FIXME [This version does not support Host Name.]
         */
 
-       retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize);
+       retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize, gfp);
        if (!retval)
                goto nodata;
 
                                        num_ext);
 
        /* Now allocate and fill out the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
+       retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize, gfp);
        if (!retval)
                goto nomem_chunk;
 
        cookie_len = asoc->peer.cookie_len;
 
        /* Build a cookie echo chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0, cookie_len);
+       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0,
+                                  cookie_len, GFP_ATOMIC);
        if (!retval)
                goto nodata;
        retval->subh.cookie_hdr =
 {
        struct sctp_chunk *retval;
 
-       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0);
+       retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0, GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
 
        cwr.lowest_tsn = htonl(lowest_tsn);
        retval = sctp_make_control(asoc, SCTP_CID_ECN_CWR, 0,
-                                  sizeof(sctp_cwrhdr_t));
+                                  sizeof(sctp_cwrhdr_t), GFP_ATOMIC);
 
        if (!retval)
                goto nodata;
 
        ecne.lowest_tsn = htonl(lowest_tsn);
        retval = sctp_make_control(asoc, SCTP_CID_ECN_ECNE, 0,
-                                  sizeof(sctp_ecnehdr_t));
+                                  sizeof(sctp_ecnehdr_t), GFP_ATOMIC);
        if (!retval)
                goto nodata;
        retval->subh.ecne_hdr =
  */
 struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
                                       const struct sctp_sndrcvinfo *sinfo,
-                                      int data_len, __u8 flags, __u16 ssn)
+                                      int data_len, __u8 flags, __u16 ssn,
+                                      gfp_t gfp)
 {
        struct sctp_chunk *retval;
        struct sctp_datahdr dp;
                dp.ssn = htons(ssn);
 
        chunk_len = sizeof(dp) + data_len;
-       retval = sctp_make_data(asoc, flags, chunk_len);
+       retval = sctp_make_data(asoc, flags, chunk_len, gfp);
        if (!retval)
                goto nodata;
 
                + sizeof(__u32) * num_dup_tsns;
 
        /* Create the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len);
+       retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len, GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
        shut.cum_tsn_ack = htonl(ctsn);
 
        retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0,
-                                  sizeof(sctp_shutdownhdr_t));
+                                  sizeof(sctp_shutdownhdr_t), GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
 {
        struct sctp_chunk *retval;
 
-       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0);
+       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0,
+                                  GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
         */
        flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
 
-       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
+       retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags,
+                                  0, GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
                        flags = SCTP_CHUNK_FLAG_T;
        }
 
-       retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint);
+       retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint,
+                                  GFP_ATOMIC);
 
        /* RFC 2960 6.4 Multi-homed SCTP Endpoints
         *
        struct sctp_chunk *retval;
        sctp_sender_hb_info_t hbinfo;
 
-       retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo));
+       retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0,
+                                  sizeof(hbinfo), GFP_ATOMIC);
 
        if (!retval)
                goto nodata;
 {
        struct sctp_chunk *retval;
 
-       retval  = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen);
+       retval  = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen,
+                                   GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
        struct sctp_chunk *retval;
 
        retval = sctp_make_control(asoc, SCTP_CID_ERROR, 0,
-                                  sizeof(sctp_errhdr_t) + size);
+                                  sizeof(sctp_errhdr_t) + size, GFP_ATOMIC);
        if (!retval)
                goto nodata;
 
                return NULL;
 
        retval = sctp_make_control(asoc, SCTP_CID_AUTH, 0,
-                       hmac_desc->hmac_len + sizeof(sctp_authhdr_t));
+                       hmac_desc->hmac_len + sizeof(sctp_authhdr_t),
+                       GFP_ATOMIC);
        if (!retval)
                return NULL;
 
  */
 struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
                            const struct sctp_association *asoc,
-                           struct sock *sk)
+                           struct sock *sk, gfp_t gfp)
 {
        struct sctp_chunk *retval;
 
-       retval = kmem_cache_zalloc(sctp_chunk_cachep, GFP_ATOMIC);
+       retval = kmem_cache_zalloc(sctp_chunk_cachep, gfp);
 
        if (!retval)
                goto nodata;
  * arguments, reserving enough space for a 'paylen' byte payload.
  */
 static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
-                                           __u8 type, __u8 flags, int paylen)
+                                           __u8 type, __u8 flags, int paylen,
+                                           gfp_t gfp)
 {
        struct sctp_chunk *retval;
        sctp_chunkhdr_t *chunk_hdr;
        struct sock *sk;
 
        /* No need to allocate LL here, as this is only a chunk. */
-       skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen),
-                       GFP_ATOMIC);
+       skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen), gfp);
        if (!skb)
                goto nodata;
 
        chunk_hdr->length = htons(sizeof(sctp_chunkhdr_t));
 
        sk = asoc ? asoc->base.sk : NULL;
-       retval = sctp_chunkify(skb, asoc, sk);
+       retval = sctp_chunkify(skb, asoc, sk, gfp);
        if (!retval) {
                kfree_skb(skb);
                goto nodata;
 }
 
 static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
-                                        __u8 flags, int paylen)
+                                        __u8 flags, int paylen, gfp_t gfp)
 {
-       return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen);
+       return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen, gfp);
 }
 
 static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
-                                           __u8 type, __u8 flags, int paylen)
+                                           __u8 type, __u8 flags, int paylen,
+                                           gfp_t gfp)
 {
-       struct sctp_chunk *chunk = _sctp_make_chunk(asoc, type, flags, paylen);
+       struct sctp_chunk *chunk;
 
+       chunk = _sctp_make_chunk(asoc, type, flags, paylen, gfp);
        if (chunk)
                sctp_control_set_owner_w(chunk);
 
        length += addrlen;
 
        /* Create the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length);
+       retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length,
+                                  GFP_ATOMIC);
        if (!retval)
                return NULL;
 
        int                     length = sizeof(asconf) + vparam_len;
 
        /* Create the chunk.  */
-       retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length);
+       retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length,
+                                  GFP_ATOMIC);
        if (!retval)
                return NULL;
 
 
        hint = (nstreams + 1) * sizeof(__u32);
 
-       retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint);
+       retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint, GFP_ATOMIC);
 
        if (!retval)
                return NULL;
 
  * encouraged for small fragments.
  */
 static int sctp_cmd_send_msg(struct sctp_association *asoc,
-                               struct sctp_datamsg *msg)
+                               struct sctp_datamsg *msg, gfp_t gfp)
 {
        struct sctp_chunk *chunk;
        int error = 0;
 
        list_for_each_entry(chunk, &msg->chunks, frag_list) {
-               error = sctp_outq_tail(&asoc->outqueue, chunk);
+               error = sctp_outq_tail(&asoc->outqueue, chunk, gfp);
                if (error)
                        break;
        }
                case SCTP_CMD_NEW_ASOC:
                        /* Register a new association.  */
                        if (local_cork) {
-                               sctp_outq_uncork(&asoc->outqueue);
+                               sctp_outq_uncork(&asoc->outqueue, gfp);
                                local_cork = 0;
                        }
 
 
                case SCTP_CMD_DELETE_TCB:
                        if (local_cork) {
-                               sctp_outq_uncork(&asoc->outqueue);
+                               sctp_outq_uncork(&asoc->outqueue, gfp);
                                local_cork = 0;
                        }
                        /* Delete the current association.  */
                                local_cork = 1;
                        }
                        /* Send a chunk to our peer.  */
-                       error = sctp_outq_tail(&asoc->outqueue, cmd->obj.chunk);
+                       error = sctp_outq_tail(&asoc->outqueue, cmd->obj.chunk,
+                                              gfp);
                        break;
 
                case SCTP_CMD_SEND_PKT:
                        /* Send a full packet to our peer.  */
                        packet = cmd->obj.packet;
-                       sctp_packet_transmit(packet);
+                       sctp_packet_transmit(packet, gfp);
                        sctp_ootb_pkt_free(packet);
                        break;
 
                         */
                        chunk->pdiscard = 1;
                        if (asoc) {
-                               sctp_outq_uncork(&asoc->outqueue);
+                               sctp_outq_uncork(&asoc->outqueue, gfp);
                                local_cork = 0;
                        }
                        break;
                case SCTP_CMD_FORCE_PRIM_RETRAN:
                        t = asoc->peer.retran_path;
                        asoc->peer.retran_path = asoc->peer.primary_path;
-                       error = sctp_outq_uncork(&asoc->outqueue);
+                       error = sctp_outq_uncork(&asoc->outqueue, gfp);
                        local_cork = 0;
                        asoc->peer.retran_path = t;
                        break;
                                sctp_outq_cork(&asoc->outqueue);
                                local_cork = 1;
                        }
-                       error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
+                       error = sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp);
                        break;
                case SCTP_CMD_SEND_NEXT_ASCONF:
                        sctp_cmd_send_asconf(asoc);
         */
        if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) {
                if (chunk->end_of_packet || chunk->singleton)
-                       error = sctp_outq_uncork(&asoc->outqueue);
+                       error = sctp_outq_uncork(&asoc->outqueue, gfp);
        } else if (local_cork)
-               error = sctp_outq_uncork(&asoc->outqueue);
+               error = sctp_outq_uncork(&asoc->outqueue, gfp);
        return error;
 nomem:
        error = -ENOMEM;