diff mbox

infiniband: Fixes memory leak in send_flowc

Message ID 1402940957-6381-1-git-send-email-xerofoify@gmail.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Nick June 16, 2014, 5:49 p.m. UTC
Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
---
 drivers/infiniband/hw/cxgb4/cm.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Steve Wise June 16, 2014, 6:18 p.m. UTC | #1
On 6/16/2014 12:49 PM, Nicholas Krause wrote:
> Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
> ---
>   drivers/infiniband/hw/cxgb4/cm.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
> index 5e153f6..867e664 100644
> --- a/drivers/infiniband/hw/cxgb4/cm.c
> +++ b/drivers/infiniband/hw/cxgb4/cm.c
> @@ -455,8 +455,11 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
>   	unsigned int flowclen = 80;
>   	struct fw_flowc_wr *flowc;
>   	int i;
> -

Please add back the above blank line.

>   	skb = get_skb(skb, flowclen, GFP_KERNEL);
> +	if (!skb) {
> +		kfree_skb(skb);

Let's do a pr_warn() here;

         pr_warn(MOD "%s failed to allocate skb.\n", __func__);


> +		return;
> +	}
>   	flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen);
>   
>   	flowc->op_to_nparams = cpu_to_be32(FW_WR_OP(FW_FLOWC_WR) |

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Rientjes June 16, 2014, 11:44 p.m. UTC | #2
On Mon, 16 Jun 2014, Steve Wise wrote:

> On 6/16/2014 12:49 PM, Nicholas Krause wrote:
> > Signed-off-by: Nicholas Krause <xerofoify@gmail.com>
> > ---
> >   drivers/infiniband/hw/cxgb4/cm.c | 5 ++++-
> >   1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/infiniband/hw/cxgb4/cm.c
> > b/drivers/infiniband/hw/cxgb4/cm.c
> > index 5e153f6..867e664 100644
> > --- a/drivers/infiniband/hw/cxgb4/cm.c
> > +++ b/drivers/infiniband/hw/cxgb4/cm.c
> > @@ -455,8 +455,11 @@ static void send_flowc(struct c4iw_ep *ep, struct
> > sk_buff *skb)
> >   	unsigned int flowclen = 80;
> >   	struct fw_flowc_wr *flowc;
> >   	int i;
> > -
> 
> Please add back the above blank line.
> 
> >   	skb = get_skb(skb, flowclen, GFP_KERNEL);
> > +	if (!skb) {
> > +		kfree_skb(skb);
> 
> Let's do a pr_warn() here;
> 
>         pr_warn(MOD "%s failed to allocate skb.\n", __func__);
> 

No need, if the allocation from skbuff_head_cache fails in the slab 
allocator, the page allocator will loop forever for orders less than 
PAGE_ALLOC_COSTLY_ORDER or spew a page allocation failure warning with a 
stack trace that indicated the high order page allocation failed in this 
path.

> 
> > +		return;
> > +	}
> >   	flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen);
> >     	flowc->op_to_nparams = cpu_to_be32(FW_WR_OP(FW_FLOWC_WR) |
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Rientjes June 17, 2014, 12:09 a.m. UTC | #3
On Mon, 16 Jun 2014, Nick Krause wrote:

> If that is the case ,David I would mark bug id 44631 as closed due to no
> need for my if statement.

You don't want to depend on the implementation of the page allocator to 
never return NULL for orders < PAGE_ALLOC_COSTLY_ORDER with GFP_KERNEL, it 
could possibly change in the future and we wouldn't catch your dependency 
in send_flowc().  The size object size of the skbuff_head_cache slab cache 
could also change.  You don't need the suggested pr_warn(), though, since 
the page allocation failure warning would also be noisy enough.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Rientjes June 17, 2014, 12:36 a.m. UTC | #4
On Mon, 16 Jun 2014, Nick Krause wrote:

> That's true David,
> I will resend this parch without the use of the pr_warn.

There's no patch to resend if you don't use pr_warn().  kfree_skb(skb) is 
unnecessary if !skb, look at the first thing it checks:

void kfree_skb(struct sk_buff *skb)
{
        if (unlikely(!skb))
                return;
	...
}

Thus, I don't see the memory leak you're referring to.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Steve Wise June 17, 2014, 1:53 p.m. UTC | #5
> -----Original Message-----
> From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-owner@vger.kernel.org] On
> Behalf Of David Rientjes
> Sent: Monday, June 16, 2014 7:37 PM
> To: Nick Krause
> Cc: Steve Wise; swise@chelsio.com; roland@kernel.org; sean.hefty@intel.com;
> hal.rosenstock@gmail.com; linux-rdma@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] infiniband: Fixes memory leak in send_flowc
> 
> On Mon, 16 Jun 2014, Nick Krause wrote:
> 
> > That's true David,
> > I will resend this parch without the use of the pr_warn.
> 
> There's no patch to resend if you don't use pr_warn().  kfree_skb(skb) is
> unnecessary if !skb, look at the first thing it checks:
> 
> void kfree_skb(struct sk_buff *skb)
> {
>         if (unlikely(!skb))
>                 return;
> 	...
> }
> 
> Thus, I don't see the memory leak you're referring to.

send_flowc() still needs to handle a NULL return from get_skb().  That is what the bug
report is addressing...

Steve.


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 5e153f6..867e664 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -455,8 +455,11 @@  static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
 	unsigned int flowclen = 80;
 	struct fw_flowc_wr *flowc;
 	int i;
-
 	skb = get_skb(skb, flowclen, GFP_KERNEL);
+	if (!skb) {
+		kfree_skb(skb);
+		return;
+	}
 	flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen);
 
 	flowc->op_to_nparams = cpu_to_be32(FW_WR_OP(FW_FLOWC_WR) |