From 825f5f3d55187eaf38baabb97a8dec86e94e8cff Mon Sep 17 00:00:00 2001 From: Eldad Zinger Date: Mon, 26 Jul 2010 10:24:05 +0300 Subject: [PATCH] sdp: fix behavior when a skb allocation fails Signed-off-by: Eldad Zinger --- drivers/infiniband/ulp/sdp/sdp.h | 9 +++++++- drivers/infiniband/ulp/sdp/sdp_bcopy.c | 29 +++++++++++++------------- drivers/infiniband/ulp/sdp/sdp_main.c | 6 ++++-- drivers/infiniband/ulp/sdp/sdp_rx.c | 5 +++-- drivers/infiniband/ulp/sdp/sdp_zcopy.c | 8 +++++++ 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/drivers/infiniband/ulp/sdp/sdp.h b/drivers/infiniband/ulp/sdp/sdp.h index 69137fb2bf87b..62e56437a9b6d 100644 --- a/drivers/infiniband/ulp/sdp/sdp.h +++ b/drivers/infiniband/ulp/sdp/sdp.h @@ -638,7 +638,8 @@ static inline struct sk_buff *sdp_alloc_skb(struct sock *sk, u8 mid, int size, } skb = sdp_stream_alloc_skb(sk, size, gfp); - BUG_ON(!skb); + if (unlikely(!skb)) + return NULL; skb_header_release(skb); @@ -667,6 +668,8 @@ static inline struct sk_buff *sdp_alloc_skb_chrcvbuf_ack(struct sock *sk, struct sdp_chrecvbuf *resp_size; skb = sdp_alloc_skb(sk, SDP_MID_CHRCVBUF_ACK, sizeof(*resp_size), gfp); + if (unlikely(!skb)) + return NULL; resp_size = (struct sdp_chrecvbuf *)skb_put(skb, sizeof *resp_size); resp_size->size = htonl(size); @@ -681,6 +684,8 @@ static inline struct sk_buff *sdp_alloc_skb_srcavail(struct sock *sk, struct sdp_srcah *srcah; skb = sdp_alloc_skb(sk, SDP_MID_SRCAVAIL, sizeof(*srcah), gfp); + if (unlikely(!skb)) + return NULL; srcah = (struct sdp_srcah *)skb_put(skb, sizeof(*srcah)); srcah->len = htonl(len); @@ -703,6 +708,8 @@ static inline struct sk_buff *sdp_alloc_skb_rdmardcompl(struct sock *sk, struct sdp_rrch *rrch; skb = sdp_alloc_skb(sk, SDP_MID_RDMARDCOMPL, sizeof(*rrch), gfp); + if (unlikely(!skb)) + return NULL; rrch = (struct sdp_rrch *)skb_put(skb, sizeof(*rrch)); rrch->len = htonl(len); diff --git a/drivers/infiniband/ulp/sdp/sdp_bcopy.c b/drivers/infiniband/ulp/sdp/sdp_bcopy.c index 6c7d700fa3e5e..663bf2b7a0ea6 100644 --- a/drivers/infiniband/ulp/sdp/sdp_bcopy.c +++ b/drivers/infiniband/ulp/sdp/sdp_bcopy.c @@ -203,13 +203,13 @@ void sdp_post_sends(struct sdp_sock *ssk, gfp_t gfp) ring_tail(ssk->rx_ring) >= ssk->recv_request_head && tx_credits(ssk) >= SDP_MIN_TX_CREDITS && sdp_tx_ring_slots_left(ssk)) { - ssk->recv_request = 0; - skb = sdp_alloc_skb_chrcvbuf_ack(sk, ssk->recv_frags * PAGE_SIZE, gfp); - - sdp_post_send(ssk, skb); - post_count++; + if (likely(skb)) { + ssk->recv_request = 0; + sdp_post_send(ssk, skb); + post_count++; + } } if (tx_credits(ssk) <= SDP_MIN_TX_CREDITS && @@ -236,10 +236,11 @@ void sdp_post_sends(struct sdp_sock *ssk, gfp_t gfp) (TCPF_ESTABLISHED | TCPF_FIN_WAIT1))) { skb = sdp_alloc_skb_data(&ssk->isk.sk, 0, gfp); - sdp_post_send(ssk, skb); - - SDPSTATS_COUNTER_INC(post_send_credits); - post_count++; + if (likely(skb)) { + sdp_post_send(ssk, skb); + SDPSTATS_COUNTER_INC(post_send_credits); + post_count++; + } } /* send DisConn if needed @@ -250,12 +251,12 @@ void sdp_post_sends(struct sdp_sock *ssk, gfp_t gfp) if (unlikely(ssk->sdp_disconnect) && !ssk->isk.sk.sk_send_head && tx_credits(ssk) > 1) { - ssk->sdp_disconnect = 0; - skb = sdp_alloc_skb_disconnect(sk, gfp); - sdp_post_send(ssk, skb); - - post_count++; + if (likely(skb)) { + ssk->sdp_disconnect = 0; + sdp_post_send(ssk, skb); + post_count++; + } } if (post_count) diff --git a/drivers/infiniband/ulp/sdp/sdp_main.c b/drivers/infiniband/ulp/sdp/sdp_main.c index 967989a2df231..424a42134ce6c 100644 --- a/drivers/infiniband/ulp/sdp/sdp_main.c +++ b/drivers/infiniband/ulp/sdp/sdp_main.c @@ -2421,8 +2421,10 @@ skip_copy: if (rx_sa && !(flags & MSG_PEEK)) { rc = sdp_post_rdma_rd_compl(sk, rx_sa, offset); - BUG_ON(rc); - + if (unlikely(rc)) { + err = rc; + goto out; + } } if (!rx_sa && offset < skb->len) diff --git a/drivers/infiniband/ulp/sdp/sdp_rx.c b/drivers/infiniband/ulp/sdp/sdp_rx.c index 44af8813d47f0..76a084d82a95a 100644 --- a/drivers/infiniband/ulp/sdp/sdp_rx.c +++ b/drivers/infiniband/ulp/sdp/sdp_rx.c @@ -172,9 +172,10 @@ static int sdp_post_recv(struct sdp_sock *ssk) gfp_page = GFP_HIGHUSER; } + if (unlikely(!skb)) + return -1; + sdp_prf(&ssk->isk.sk, skb, "Posting skb"); - /* FIXME */ - BUG_ON(!skb); h = (struct sdp_bsdh *)skb->head; rx_req = ssk->rx_ring.buffer + (id & (SDP_RX_SIZE - 1)); diff --git a/drivers/infiniband/ulp/sdp/sdp_zcopy.c b/drivers/infiniband/ulp/sdp/sdp_zcopy.c index 1ab67f038d40d..5994313d7aa42 100644 --- a/drivers/infiniband/ulp/sdp/sdp_zcopy.c +++ b/drivers/infiniband/ulp/sdp/sdp_zcopy.c @@ -117,6 +117,9 @@ static int sdp_post_srcavail_cancel(struct sock *sk) sdp_dbg_data(&ssk->isk.sk, "Posting srcavail cancel\n"); skb = sdp_alloc_skb_srcavail_cancel(sk, 0); + if (unlikely(!skb)) + return -ENOMEM; + sdp_skb_entail(sk, skb); sdp_post_sends(ssk, 0); @@ -285,6 +288,8 @@ int sdp_post_rdma_rd_compl(struct sock *sk, return 0; skb = sdp_alloc_skb_rdmardcompl(sk, copied, 0); + if (unlikely(!skb)) + return -ENOMEM; sdp_skb_entail(sk, skb); @@ -299,6 +304,9 @@ int sdp_post_sendsm(struct sock *sk) { struct sk_buff *skb = sdp_alloc_skb_sendsm(sk, 0); + if (unlikely(!skb)) + return -ENOMEM; + sdp_skb_entail(sk, skb); sdp_post_sends(sdp_sk(sk), 0); -- 2.49.0