From patchwork Thu Aug 25 00:55:20 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Blanchard X-Patchwork-Id: 111438 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id CFC35B6F69 for ; Thu, 25 Aug 2011 10:55:27 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752715Ab1HYAzX (ORCPT ); Wed, 24 Aug 2011 20:55:23 -0400 Received: from ozlabs.org ([203.10.76.45]:43518 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750915Ab1HYAzW (ORCPT ); Wed, 24 Aug 2011 20:55:22 -0400 Received: from kryten (ppp121-45-171-79.lns20.syd6.internode.on.net [121.45.171.79]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPSA id 0D901B6EE8; Thu, 25 Aug 2011 10:55:21 +1000 (EST) Date: Thu, 25 Aug 2011 10:55:20 +1000 From: Anton Blanchard To: David Miller Cc: santil@linux.vnet.ibm.com, netdev@vger.kernel.org Subject: [PATCH] ibmveth: Fix leak when recycling skb and hypervisor returns error Message-ID: <20110825105520.5ba7ae90@kryten> In-Reply-To: <20110824.174353.1962229766905714384.davem@davemloft.net> References: <20110825092019.777aea6e@kryten> <20110824.174353.1962229766905714384.davem@davemloft.net> X-Mailer: Claws Mail 3.7.8 (GTK+ 2.24.4; i686-pc-linux-gnu) Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Hi Dave, > Please generate this patch against Linus's tree, instead of -next Sure, here it is. Anton --- If h_add_logical_lan_buffer returns an error we need to free the skb. Signed-off-by: Anton Blanchard Cc: stable --- -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux-2.6-work/drivers/net/ibmveth.c =================================================================== --- linux-2.6-work.orig/drivers/net/ibmveth.c 2011-07-31 20:45:29.729141545 +1000 +++ linux-2.6-work/drivers/net/ibmveth.c 2011-08-25 10:49:04.200718870 +1000 @@ -395,7 +395,7 @@ static inline struct sk_buff *ibmveth_rx } /* recycle the current buffer on the rx queue */ -static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) +static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) { u32 q_index = adapter->rx_queue.index; u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator; @@ -403,6 +403,7 @@ static void ibmveth_rxq_recycle_buffer(s unsigned int index = correlator & 0xffffffffUL; union ibmveth_buf_desc desc; unsigned long lpar_rc; + int ret = 1; BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); BUG_ON(index >= adapter->rx_buff_pool[pool].size); @@ -410,7 +411,7 @@ static void ibmveth_rxq_recycle_buffer(s if (!adapter->rx_buff_pool[pool].active) { ibmveth_rxq_harvest_buffer(adapter); ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); - return; + goto out; } desc.fields.flags_len = IBMVETH_BUF_VALID | @@ -423,12 +424,16 @@ static void ibmveth_rxq_recycle_buffer(s netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " "during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); + ret = 0; } if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { adapter->rx_queue.index = 0; adapter->rx_queue.toggle = !adapter->rx_queue.toggle; } + +out: + return ret; } static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) @@ -1084,8 +1089,9 @@ restart_poll: if (rx_flush) ibmveth_flush_buffer(skb->data, length + offset); + if (!ibmveth_rxq_recycle_buffer(adapter)) + kfree_skb(skb); skb = new_skb; - ibmveth_rxq_recycle_buffer(adapter); } else { ibmveth_rxq_harvest_buffer(adapter); skb_reserve(skb, offset);