Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next-2.6 0/4] qlcnic: Bug fixes
From: Anirban Chakraborty @ 2010-12-03  6:41 UTC (permalink / raw)
  To: David Miller, netdev@vger.kernel.org; +Cc: Dept_NX_Linux_NIC_Driver

Please apply the following series to net-next.

thanks,
Anirban


^ permalink raw reply

* [PATCH net-next-2.6 1/4] qlcnic: Disable loopback support
From: Anirban Chakraborty @ 2010-12-03  6:41 UTC (permalink / raw)
  To: David Miller, netdev@vger.kernel.org; +Cc: Dept_NX_Linux_NIC_Driver

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Loopback mode can not be supported in CNA mode. Removing it until FW is fixed. 

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h         |    7 --
 drivers/net/qlcnic/qlcnic_ethtool.c |  104 +----------------------------------
 drivers/net/qlcnic/qlcnic_hw.c      |   53 ------------------
 drivers/net/qlcnic/qlcnic_init.c    |   93 -------------------------------
 drivers/net/qlcnic/qlcnic_main.c    |   55 ------------------
 5 files changed, 1 insertions(+), 311 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 9513a83..1fd476d 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -798,7 +798,6 @@ struct qlcnic_nic_intr_coalesce {
 #define QLCNIC_H2C_OPCODE_GET_NET_STATS 		16
 #define QLCNIC_H2C_OPCODE_PROXY_UPDATE_P2V		17
 #define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 		18
-#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK		19
 #define QLCNIC_H2C_OPCODE_PROXY_STOP_DONE		20
 #define QLCNIC_H2C_OPCODE_GET_LINKEVENT 		21
 #define QLCNIC_C2C_OPCODE				22
@@ -1314,21 +1313,15 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
 int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
 void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
 		struct qlcnic_host_tx_ring *tx_ring);
-void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter);
-int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter);
 void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
 
 /* Functions from qlcnic_main.c */
-int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter);
-void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter);
 int qlcnic_reset_context(struct qlcnic_adapter *);
 u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
 	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd);
 void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
 int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
-int qlcnic_check_loopback_buff(unsigned char *data);
 netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
-void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
 
 /* Management functions */
 int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index c389296..2aa9d8b 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -101,8 +101,7 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Register_Test_on_offline",
 	"Link_Test_on_offline",
-	"Interrupt_Test_offline",
-	"Loopback_Test_offline"
+	"Interrupt_Test_offline"
 };
 
 #define QLCNIC_TEST_LEN	ARRAY_SIZE(qlcnic_gstrings_test)
@@ -643,104 +642,6 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset)
 	}
 }
 
-#define QLC_ILB_PKT_SIZE 64
-#define QLC_NUM_ILB_PKT	16
-#define QLC_ILB_MAX_RCV_LOOP 10
-
-static void qlcnic_create_loopback_buff(unsigned char *data)
-{
-	unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
-	memset(data, 0x4e, QLC_ILB_PKT_SIZE);
-	memset(data, 0xff, 12);
-	memcpy(data + 12, random_data, sizeof(random_data));
-}
-
-int qlcnic_check_loopback_buff(unsigned char *data)
-{
-	unsigned char buff[QLC_ILB_PKT_SIZE];
-	qlcnic_create_loopback_buff(buff);
-	return memcmp(data, buff, QLC_ILB_PKT_SIZE);
-}
-
-static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter)
-{
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
-	struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
-	struct sk_buff *skb;
-	int i, loop, cnt = 0;
-
-	for (i = 0; i < QLC_NUM_ILB_PKT; i++) {
-		skb = dev_alloc_skb(QLC_ILB_PKT_SIZE);
-		qlcnic_create_loopback_buff(skb->data);
-		skb_put(skb, QLC_ILB_PKT_SIZE);
-
-		adapter->diag_cnt = 0;
-		qlcnic_xmit_frame(skb, adapter->netdev);
-
-		loop = 0;
-		do {
-			msleep(1);
-			qlcnic_process_rcv_ring_diag(sds_ring);
-		} while (loop++ < QLC_ILB_MAX_RCV_LOOP &&
-			 !adapter->diag_cnt);
-
-		dev_kfree_skb_any(skb);
-
-		if (!adapter->diag_cnt)
-			dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet"
-				" not recevied\n", i + 1);
-		else
-			cnt++;
-	}
-	if (cnt != i) {
-		dev_warn(&adapter->pdev->dev, "ILB Test failed\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int qlcnic_loopback_test(struct net_device *netdev)
-{
-	struct qlcnic_adapter *adapter = netdev_priv(netdev);
-	int max_sds_rings = adapter->max_sds_rings;
-	int ret;
-
-	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
-		dev_warn(&adapter->pdev->dev, "Loopback test not supported"
-				"for non privilege function\n");
-		return 0;
-	}
-
-	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
-		return -EIO;
-
-	if (qlcnic_request_quiscent_mode(adapter)) {
-		clear_bit(__QLCNIC_RESETTING, &adapter->state);
-		return -EIO;
-	}
-
-	ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
-	if (ret)
-		goto clear_it;
-
-	ret = qlcnic_set_ilb_mode(adapter);
-	if (ret)
-		goto done;
-
-	ret = qlcnic_do_ilb_test(adapter);
-
-	qlcnic_clear_ilb_mode(adapter);
-
-done:
-	qlcnic_diag_free_res(netdev, max_sds_rings);
-
-clear_it:
-	qlcnic_clear_quiscent_mode(adapter);
-	adapter->max_sds_rings = max_sds_rings;
-	clear_bit(__QLCNIC_RESETTING, &adapter->state);
-	return ret;
-}
-
 static int qlcnic_irq_test(struct net_device *netdev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -793,9 +694,6 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 		if (data[2])
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
-		data[3] = qlcnic_loopback_test(dev);
-		if (data[3])
-			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 	}
 }
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 7a47a2a..8630118 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1234,56 +1234,3 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
 
 	return rv;
 }
-
-static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u32 flag)
-{
-	struct qlcnic_nic_req	req;
-	int			rv;
-	u64			word;
-
-	memset(&req, 0, sizeof(struct qlcnic_nic_req));
-	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
-
-	word = QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK |
-			((u64)adapter->portnum << 16);
-	req.req_hdr = cpu_to_le64(word);
-	req.words[0] = cpu_to_le64(flag);
-
-	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
-	if (rv)
-		dev_err(&adapter->pdev->dev,
-			"%sting loopback mode failed.\n",
-					flag ? "Set" : "Reset");
-	return rv;
-}
-
-int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter)
-{
-	if (qlcnic_set_fw_loopback(adapter, 1))
-		return -EIO;
-
-	if (qlcnic_nic_set_promisc(adapter,
-				VPORT_MISS_MODE_ACCEPT_ALL)) {
-		qlcnic_set_fw_loopback(adapter, 0);
-		return -EIO;
-	}
-
-	msleep(1000);
-	return 0;
-}
-
-void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter)
-{
-	int mode = VPORT_MISS_MODE_DROP;
-	struct net_device *netdev = adapter->netdev;
-
-	qlcnic_set_fw_loopback(adapter, 0);
-
-	if (netdev->flags & IFF_PROMISC)
-		mode = VPORT_MISS_MODE_ACCEPT_ALL;
-	else if (netdev->flags & IFF_ALLMULTI)
-		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
-
-	qlcnic_nic_set_promisc(adapter, mode);
-	msleep(1000);
-}
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index c5ea2f4..6d0ec6c 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1690,99 +1690,6 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
 	spin_unlock(&rds_ring->lock);
 }
 
-static void dump_skb(struct sk_buff *skb)
-{
-	int i;
-	unsigned char *data = skb->data;
-
-	for (i = 0; i < skb->len; i++) {
-		printk("%02x ", data[i]);
-		if ((i & 0x0f) == 8)
-			printk("\n");
-	}
-}
-
-static struct qlcnic_rx_buffer *
-qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
-		struct qlcnic_host_sds_ring *sds_ring,
-		int ring, u64 sts_data0)
-{
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
-	struct qlcnic_rx_buffer *buffer;
-	struct sk_buff *skb;
-	struct qlcnic_host_rds_ring *rds_ring;
-	int index, length, cksum, pkt_offset;
-
-	if (unlikely(ring >= adapter->max_rds_rings))
-		return NULL;
-
-	rds_ring = &recv_ctx->rds_rings[ring];
-
-	index = qlcnic_get_sts_refhandle(sts_data0);
-	if (unlikely(index >= rds_ring->num_desc))
-		return NULL;
-
-	buffer = &rds_ring->rx_buf_arr[index];
-
-	length = qlcnic_get_sts_totallength(sts_data0);
-	cksum  = qlcnic_get_sts_status(sts_data0);
-	pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0);
-
-	skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
-	if (!skb)
-		return buffer;
-
-	if (length > rds_ring->skb_size)
-		skb_put(skb, rds_ring->skb_size);
-	else
-		skb_put(skb, length);
-
-	if (pkt_offset)
-		skb_pull(skb, pkt_offset);
-
-	if (!qlcnic_check_loopback_buff(skb->data))
-		adapter->diag_cnt++;
-	else
-		dump_skb(skb);
-
-	dev_kfree_skb_any(skb);
-	adapter->stats.rx_pkts++;
-	adapter->stats.rxbytes += length;
-
-	return buffer;
-}
-
-void
-qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
-{
-	struct qlcnic_adapter *adapter = sds_ring->adapter;
-	struct status_desc *desc;
-	struct qlcnic_rx_buffer *rxbuf;
-	u64 sts_data0;
-
-	int opcode, ring, desc_cnt;
-	u32 consumer = sds_ring->consumer;
-
-	desc = &sds_ring->desc_head[consumer];
-	sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
-
-	if (!(sts_data0 & STATUS_OWNER_HOST))
-		return;
-
-	desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
-	opcode = qlcnic_get_sts_opcode(sts_data0);
-
-	ring = qlcnic_get_sts_type(sts_data0);
-	rxbuf = qlcnic_process_rcv_diag(adapter, sds_ring,
-					ring, sts_data0);
-
-	desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
-	consumer = get_next_index(consumer, sds_ring->num_desc);
-
-	sds_ring->consumer = consumer;
-	writel(consumer, sds_ring->crb_sts_consumer);
-}
-
 void
 qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2,
 			u8 alt_mac, u8 *mac)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 899df5a..08d4b37 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2859,61 +2859,6 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
 	qlcnic_api_unlock(adapter);
 }
 
-/* Caller should held RESETTING bit.
- * This should be call in sync with qlcnic_request_quiscent_mode.
- */
-void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter)
-{
-	qlcnic_clr_drv_state(adapter);
-	qlcnic_api_lock(adapter);
-	QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
-	qlcnic_api_unlock(adapter);
-}
-
-/* Caller should held RESETTING bit.
- */
-int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter)
-{
-	u8 timeo = adapter->dev_init_timeo / 2;
-	u32 state;
-
-	if (qlcnic_api_lock(adapter))
-		return -EIO;
-
-	state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
-	if (state != QLCNIC_DEV_READY)
-		return -EIO;
-
-	QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT);
-	qlcnic_api_unlock(adapter);
-	QLCDB(adapter, DRV, "NEED QUISCENT state set\n");
-	qlcnic_idc_debug_info(adapter, 0);
-
-	qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT);
-
-	do {
-		msleep(2000);
-		state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
-		if (state == QLCNIC_DEV_QUISCENT)
-			return 0;
-		if (!qlcnic_check_drv_state(adapter)) {
-			if (qlcnic_api_lock(adapter))
-				return -EIO;
-			QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
-							QLCNIC_DEV_QUISCENT);
-			qlcnic_api_unlock(adapter);
-			QLCDB(adapter, DRV, "QUISCENT mode set\n");
-			return 0;
-		}
-	} while (--timeo);
-
-	dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x"
-		" DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE),
-		QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE));
-	qlcnic_clear_quiscent_mode(adapter);
-	return -EIO;
-}
-
 /*Transit to RESET state from READY state only */
 static void
 qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
-- 
1.5.4.5


^ permalink raw reply related

* [PATCH net-next-2.6 2/4] qlcnic: validate eswitch config values for PF
From: Anirban Chakraborty @ 2010-12-03  6:41 UTC (permalink / raw)
  To: David Miller, netdev@vger.kernel.org; +Cc: Dept_NX_Linux_NIC_Driver

From: Amit Kumar Salecha <amit.salecha@qlogic.com>

Currently driver set default eswitch configuration values for PF function,
instead of validating values sent by application.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 08d4b37..4e8466b 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -3537,9 +3537,12 @@ validate_esw_config(struct qlcnic_adapter *adapter,
 		case QLCNIC_PORT_DEFAULTS:
 			if (QLC_DEV_GET_DRV(op_mode, pci_func) !=
 						QLCNIC_NON_PRIV_FUNC) {
-				esw_cfg[i].mac_anti_spoof = 0;
-				esw_cfg[i].mac_override = 1;
-				esw_cfg[i].promisc_mode = 1;
+				if (esw_cfg[i].mac_anti_spoof != 0)
+					return QL_STATUS_INVALID_PARAM;
+				if (esw_cfg[i].mac_override != 1)
+					return QL_STATUS_INVALID_PARAM;
+				if (esw_cfg[i].promisc_mode != 1)
+					return QL_STATUS_INVALID_PARAM;
 			}
 			break;
 		case QLCNIC_ADD_VLAN:
-- 
1.5.4.5


^ permalink raw reply related

* [PATCH net-next-2.6 3/4] qlcnic: LICENSE file for qlcnic
From: Anirban Chakraborty @ 2010-12-03  6:41 UTC (permalink / raw)
  To: David Miller, netdev@vger.kernel.org; +Cc: Dept_NX_Linux_NIC_Driver

From: Sritej Velaga <sritej.velaga@qlogic.com>

Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 Documentation/networking/LICENSE.qlcnic |  327 +++++++++++++++++++++++++++++++
 drivers/net/qlcnic/qlcnic.h             |   23 +--
 drivers/net/qlcnic/qlcnic_ctx.c         |   23 +--
 drivers/net/qlcnic/qlcnic_ethtool.c     |   23 +--
 drivers/net/qlcnic/qlcnic_hdr.h         |   23 +--
 drivers/net/qlcnic/qlcnic_hw.c          |   23 +--
 drivers/net/qlcnic/qlcnic_init.c        |   23 +--
 drivers/net/qlcnic/qlcnic_main.c        |   23 +--
 8 files changed, 348 insertions(+), 140 deletions(-)
 create mode 100644 Documentation/networking/LICENSE.qlcnic

diff --git a/Documentation/networking/LICENSE.qlcnic b/Documentation/networking/LICENSE.qlcnic
new file mode 100644
index 0000000..8c991be
--- /dev/null
+++ b/Documentation/networking/LICENSE.qlcnic
@@ -0,0 +1,327 @@
+Copyright (c) 2009-2010 QLogic Corporation
+QLogic Linux qlcnic NIC Driver
+
+This program includes a device driver for Linux 2.6 that may be
+distributed with QLogic hardware specific firmware binary file.
+You may modify and redistribute the device driver code under the
+GNU General Public License (a copy of which is attached hereto as
+Exhibit A) published by the Free Software Foundation (version 2).
+
+You may redistribute the hardware specific firmware binary file
+under the following terms:
+
+       1. Redistribution of source code (only if applicable),
+          must retain the above copyright notice, this list of
+          conditions and the following disclaimer.
+
+       2. Redistribution in binary form must reproduce the above
+          copyright notice, this list of conditions and the
+          following disclaimer in the documentation and/or other
+          materials provided with the distribution.
+
+       3. The name of QLogic Corporation may not be used to
+          endorse or promote products derived from this software
+          without specific prior written permission
+
+REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
+THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
+CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
+OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
+TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
+ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
+COMBINATION WITH THIS PROGRAM.
+
+
+EXHIBIT A
+
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 1fd476d..952d409 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1,25 +1,8 @@
 /*
- * Copyright (C) 2009 - QLogic Corporation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c)  2009-2010 QLogic Corporation
  *
+ * See LICENSE.qlcnic for copyright and licensing details.
  */

 #ifndef _QLCNIC_H_
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 29cbc2a..27631f2 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -1,25 +1,8 @@
 /*
- * Copyright (C) 2009 - QLogic Corporation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c)  2009-2010 QLogic Corporation
  *
+ * See LICENSE.qlcnic for copyright and licensing details.
  */

 #include "qlcnic.h"
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 2aa9d8b..0eaf31b 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -1,25 +1,8 @@
 /*
- * Copyright (C) 2009 - QLogic Corporation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c)  2009-2010 QLogic Corporation
  *
+ * See LICENSE.qlcnic for copyright and licensing details.
  */

 #include <linux/types.h>
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 566e0e8..19328e0 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -1,25 +1,8 @@
 /*
- * Copyright (C) 2009 - QLogic Corporation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c)  2009-2010 QLogic Corporation
  *
+ * See LICENSE.qlcnic for copyright and licensing details.
  */

 #ifndef __QLCNIC_HDR_H_
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 8630118..c9c4bf1 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1,25 +1,8 @@
 /*
- * Copyright (C) 2009 - QLogic Corporation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c)  2009-2010 QLogic Corporation
  *
+ * See LICENSE.qlcnic for copyright and licensing details.
  */

 #include "qlcnic.h"
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 6d0ec6c..9b9c7c3 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1,25 +1,8 @@
 /*
- * Copyright (C) 2009 - QLogic Corporation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c)  2009-2010 QLogic Corporation
  *
+ * See LICENSE.qlcnic for copyright and licensing details.
  */

 #include <linux/netdevice.h>
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 4e8466b..788850e 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1,25 +1,8 @@
 /*
- * Copyright (C) 2009 - QLogic Corporation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called "COPYING".
+ * QLogic qlcnic NIC Driver
+ * Copyright (c)  2009-2010 QLogic Corporation
  *
+ * See LICENSE.qlcnic for copyright and licensing details.
  */

 #include <linux/slab.h>
--
1.5.4.5


^ permalink raw reply related

* [PATCH net-next-2.6 4/4] qlcnic: Updated driver version to 5.0.13
From: Anirban Chakraborty @ 2010-12-03  6:42 UTC (permalink / raw)
  To: David Miller, netdev@vger.kernel.org; +Cc: Dept_NX_Linux_NIC_Driver


Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 952d409..f267da4 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -34,8 +34,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 12
-#define QLCNIC_LINUX_VERSIONID  "5.0.12"
+#define _QLCNIC_LINUX_SUBVERSION 13
+#define QLCNIC_LINUX_VERSIONID  "5.0.13"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
-- 
1.5.4.5


^ permalink raw reply related

* [PATCH v2 0/3] bonding: add the debugfs interface to see RLB hash table
From: Taku Izumi @ 2010-12-03  7:19 UTC (permalink / raw)
  To: netdev@vger.kernel.org, Jay Vosburgh; +Cc: eric.dumazet, shemminger

Hi Jay,

Thank you for your quick review. I update my patchset according to your comment.
But I didn't take measures against your concern about seq_file. If I come up with
a good idea, I'll correct it.

--
This patchset provides the debugfs facility to the bonding driver and
the interface to see RLB hashtable in it.

 *[PATCH 1/3] bonding: add the debugfs facility to the bonding driver
 *[PATCH 2/3] bonding: migrate some macros from bond_alb.c to bond_alb.h
 *[PATCH 3/3] bonding: add the debugfs interface to see RLB hash table

Best regards,
Taku Izumi


^ permalink raw reply

* [PATCH 1/3] bonding: add the debugfs facility to the bonding driver
From: Taku Izumi @ 2010-12-03  7:21 UTC (permalink / raw)
  To: netdev@vger.kernel.org, Jay Vosburgh; +Cc: eric.dumazet, shemminger
In-Reply-To: <4CF89A00.8030902@jp.fujitsu.com>


This patch provides the debugfs facility to the bonding driver.
The "bonding" directory is created in the debugfs root and directories of
each bonding interface (like bond0, bond1...) are created in that.

 # mount -t debugfs none /sys/kernel/debug

 # ls /sys/kernel/debug/bonding
 bond0  bond1

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>

---
 drivers/net/bonding/Makefile       |    2
 drivers/net/bonding/bond_debugfs.c |   92 +++++++++++++++++++++++++++++++++++++
 drivers/net/bonding/bond_main.c    |   10 +++-
 drivers/net/bonding/bonding.h      |    9 +++
 4 files changed, 111 insertions(+), 2 deletions(-)

Index: net-next/drivers/net/bonding/bond_main.c
===================================================================
--- net-next.orig/drivers/net/bonding/bond_main.c
+++ net-next/drivers/net/bonding/bond_main.c
@@ -3507,6 +3507,8 @@ static int bond_event_changename(struct
 	bond_remove_proc_entry(bond);
 	bond_create_proc_entry(bond);

+	bond_debug_reregister(bond);
+
 	return NOTIFY_DONE;
 }

@@ -4789,6 +4791,8 @@ static void bond_uninit(struct net_devic

 	bond_remove_proc_entry(bond);

+	bond_debug_unregister(bond);
+
 	__hw_addr_flush(&bond->mc_list);

 	list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) {
@@ -5191,6 +5195,8 @@ static int bond_init(struct net_device *

 	bond_prepare_sysfs_group(bond);

+	bond_debug_register(bond);
+
 	__hw_addr_init(&bond->mc_list);
 	return 0;
 }
@@ -5312,6 +5318,8 @@ static int __init bonding_init(void)
 	if (res)
 		goto err_link;

+	bond_create_debugfs();
+
 	for (i = 0; i < max_bonds; i++) {
 		res = bond_create(&init_net, NULL);
 		if (res)
@@ -5322,7 +5330,6 @@ static int __init bonding_init(void)
 	if (res)
 		goto err;

-
 	register_netdevice_notifier(&bond_netdev_notifier);
 	register_inetaddr_notifier(&bond_inetaddr_notifier);
 	bond_register_ipv6_notifier();
@@ -5346,6 +5353,7 @@ static void __exit bonding_exit(void)
 	bond_unregister_ipv6_notifier();

 	bond_destroy_sysfs();
+	bond_destroy_debugfs();

 	rtnl_link_unregister(&bond_link_ops);
 	unregister_pernet_subsys(&bond_net_ops);
Index: net-next/drivers/net/bonding/Makefile
===================================================================
--- net-next.orig/drivers/net/bonding/Makefile
+++ net-next/drivers/net/bonding/Makefile
@@ -4,7 +4,7 @@

 obj-$(CONFIG_BONDING) += bonding.o

-bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o

 ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o
 bonding-objs += $(ipv6-y)
Index: net-next/drivers/net/bonding/bond_debugfs.c
===================================================================
--- /dev/null
+++ net-next/drivers/net/bonding/bond_debugfs.c
@@ -0,0 +1,92 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+
+#include "bonding.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static struct dentry *bonding_debug_root;
+
+void bond_debug_register(struct bonding *bond)
+{
+	if (!bonding_debug_root)
+		return;
+
+	bond->debug_dir =
+		debugfs_create_dir(bond->dev->name, bonding_debug_root);
+
+	if (!bond->debug_dir) {
+		pr_warning("%s: Warning: failed to register to debugfs\n",
+			bond->dev->name);
+		return;
+	}
+}
+
+void bond_debug_unregister(struct bonding *bond)
+{
+	debugfs_remove_recursive(bond->debug_dir);
+}
+
+void bond_debug_reregister(struct bonding *bond)
+{
+	struct dentry *d;
+
+	if (!bonding_debug_root)
+		return;
+
+	d = debugfs_rename(bonding_debug_root, bond->debug_dir,
+			   bonding_debug_root, bond->dev->name);
+	if (d) {
+		bond->debug_dir = d;
+	} else {
+		pr_warning("%s: Warning: failed to reregister, "
+				"so just unregister old one\n",
+				bond->dev->name);
+		bond_debug_unregister(bond);
+	}
+}
+
+void bond_create_debugfs(void)
+{
+	bonding_debug_root = debugfs_create_dir("bonding", NULL);
+
+	if (!bonding_debug_root) {
+		pr_warning("Warning: Cannot create bonding directory"
+				" in debugfs\n");
+	}
+}
+
+void bond_destroy_debugfs(void)
+{
+	debugfs_remove_recursive(bonding_debug_root);
+}
+
+
+#else /* !CONFIG_DEBUG_FS */
+
+void bond_debug_register(struct bonding *bond)
+{
+}
+
+void bond_debug_unregister(struct bonding *bond)
+{
+}
+
+void bond_debug_reregister(struct bonding *bond)
+{
+}
+
+void bond_create_debugfs(void)
+{
+}
+
+void bond_destroy_debugfs(void)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
Index: net-next/drivers/net/bonding/bonding.h
===================================================================
--- net-next.orig/drivers/net/bonding/bonding.h
+++ net-next/drivers/net/bonding/bonding.h
@@ -259,6 +259,10 @@ struct bonding {
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct   in6_addr master_ipv6;
 #endif
+#ifdef CONFIG_DEBUG_FS
+	/* debugging suport via debugfs */
+	struct	 dentry *debug_dir;
+#endif /* CONFIG_DEBUG_FS */
 };

 /**
@@ -380,6 +384,11 @@ void bond_select_active_slave(struct bon
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_register_arp(struct bonding *);
 void bond_unregister_arp(struct bonding *);
+void bond_create_debugfs(void);
+void bond_destroy_debugfs(void);
+void bond_debug_register(struct bonding *bond);
+void bond_debug_unregister(struct bonding *bond);
+void bond_debug_reregister(struct bonding *bond);

 struct bond_net {
 	struct net *		net;	/* Associated network namespace */



^ permalink raw reply

* [PATCH 2/3] bonding: migrate some macros from bond_alb.c to bond_alb.h
From: Taku Izumi @ 2010-12-03  7:22 UTC (permalink / raw)
  To: netdev@vger.kernel.org, Jay Vosburgh; +Cc: eric.dumazet, shemminger
In-Reply-To: <4CF89A00.8030902@jp.fujitsu.com>


This patch simply migrates some macros from bond_alb.c to bond_alb.h.


Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>

---
 drivers/net/bonding/bond_alb.c |   36 ------------------------------------
 drivers/net/bonding/bond_alb.h |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 36 deletions(-)

Index: net-next/drivers/net/bonding/bond_alb.c
===================================================================
--- net-next.orig/drivers/net/bonding/bond_alb.c
+++ net-next/drivers/net/bonding/bond_alb.c
@@ -44,42 +44,6 @@
 #include "bond_alb.h"


-#define ALB_TIMER_TICKS_PER_SEC	    10	/* should be a divisor of HZ */
-#define BOND_TLB_REBALANCE_INTERVAL 10	/* In seconds, periodic re-balancing.
-					 * Used for division - never set
-					 * to zero !!!
-					 */
-#define BOND_ALB_LP_INTERVAL	    1	/* In seconds, periodic send of
-					 * learning packets to the switch
-					 */
-
-#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
-				  * ALB_TIMER_TICKS_PER_SEC)
-
-#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
-			   * ALB_TIMER_TICKS_PER_SEC)
-
-#define TLB_HASH_TABLE_SIZE 256	/* The size of the clients hash table.
-				 * Note that this value MUST NOT be smaller
-				 * because the key hash table is BYTE wide !
-				 */
-
-
-#define TLB_NULL_INDEX		0xffffffff
-#define MAX_LP_BURST		3
-
-/* rlb defs */
-#define RLB_HASH_TABLE_SIZE	256
-#define RLB_NULL_INDEX		0xffffffff
-#define RLB_UPDATE_DELAY	2*ALB_TIMER_TICKS_PER_SEC /* 2 seconds */
-#define RLB_ARP_BURST_SIZE	2
-#define RLB_UPDATE_RETRY	3	/* 3-ticks - must be smaller than the rlb
-					 * rebalance interval (5 min).
-					 */
-/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
- * promiscuous after failover
- */
-#define RLB_PROMISC_TIMEOUT	10*ALB_TIMER_TICKS_PER_SEC

 #ifndef __long_aligned
 #define __long_aligned __attribute__((aligned((sizeof(long)))))
Index: net-next/drivers/net/bonding/bond_alb.h
===================================================================
--- net-next.orig/drivers/net/bonding/bond_alb.h
+++ net-next/drivers/net/bonding/bond_alb.h
@@ -31,6 +31,44 @@ struct slave;
 #define BOND_ALB_INFO(bond)   ((bond)->alb_info)
 #define SLAVE_TLB_INFO(slave) ((slave)->tlb_info)

+#define ALB_TIMER_TICKS_PER_SEC	    10	/* should be a divisor of HZ */
+#define BOND_TLB_REBALANCE_INTERVAL 10	/* In seconds, periodic re-balancing.
+					 * Used for division - never set
+					 * to zero !!!
+					 */
+#define BOND_ALB_LP_INTERVAL	    1	/* In seconds, periodic send of
+					 * learning packets to the switch
+					 */
+
+#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
+				  * ALB_TIMER_TICKS_PER_SEC)
+
+#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
+			   * ALB_TIMER_TICKS_PER_SEC)
+
+#define TLB_HASH_TABLE_SIZE 256	/* The size of the clients hash table.
+				 * Note that this value MUST NOT be smaller
+				 * because the key hash table is BYTE wide !
+				 */
+
+
+#define TLB_NULL_INDEX		0xffffffff
+#define MAX_LP_BURST		3
+
+/* rlb defs */
+#define RLB_HASH_TABLE_SIZE	256
+#define RLB_NULL_INDEX		0xffffffff
+#define RLB_UPDATE_DELAY	(2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */
+#define RLB_ARP_BURST_SIZE	2
+#define RLB_UPDATE_RETRY	3 /* 3-ticks - must be smaller than the rlb
+				   * rebalance interval (5 min).
+				   */
+/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
+ * promiscuous after failover
+ */
+#define RLB_PROMISC_TIMEOUT	(10*ALB_TIMER_TICKS_PER_SEC)
+
+
 struct tlb_client_info {
 	struct slave *tx_slave;	/* A pointer to slave used for transmiting
 				 * packets to a Client that the Hash function



^ permalink raw reply

* [PATCH 3/3] bonding: add the debugfs interface to see RLB hash table
From: Taku Izumi @ 2010-12-03  7:22 UTC (permalink / raw)
  To: netdev@vger.kernel.org, Jay Vosburgh; +Cc: eric.dumazet, shemminger
In-Reply-To: <4CF89A00.8030902@jp.fujitsu.com>


This patch provices the debugfs interface to see RLB hash table
like the following:

# cat /sys/kernel/debug/bonding/bond0/rlb_hash_table
SourceIP        DestinationIP   Destination MAC   DEV
10.124.196.205  10.124.196.205  ff:ff:ff:ff:ff:ff eth4
10.124.196.205  10.124.196.81   00:19:99:XX:XX:XX eth3
10.124.196.205  10.124.196.1    00:21:d8:XX:XX:XX eth0

This is helpful to check if the receive load balancing works as expected.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>

---
 drivers/net/bonding/bond_debugfs.c |   50 +++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

Index: net-next/drivers/net/bonding/bond_debugfs.c
===================================================================
--- net-next.orig/drivers/net/bonding/bond_debugfs.c
+++ net-next/drivers/net/bonding/bond_debugfs.c
@@ -4,6 +4,7 @@
 #include <linux/netdevice.h>

 #include "bonding.h"
+#include "bond_alb.h"

 #ifdef CONFIG_DEBUG_FS

@@ -12,6 +13,52 @@

 static struct dentry *bonding_debug_root;

+/*
+ *  Show RLB hash table
+ */
+static int bond_debug_rlb_hash_show(struct seq_file *m, void *v)
+{
+	struct bonding *bond = m->private;
+	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+	struct rlb_client_info *client_info;
+	u32 hash_index;
+
+	if (bond->params.mode != BOND_MODE_ALB)
+		return 0;
+
+	seq_printf(m, "SourceIP        DestinationIP   "
+			"Destination MAC   DEV\n");
+
+	spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+
+	hash_index = bond_info->rx_hashtbl_head;
+	for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+		client_info = &(bond_info->rx_hashtbl[hash_index]);
+		seq_printf(m, "%-15pI4 %-15pI4 %-17pM %s\n",
+			&client_info->ip_src,
+			&client_info->ip_dst,
+			&client_info->mac_dst,
+			client_info->slave->dev->name);
+	}
+
+	spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+
+	return 0;
+}
+
+static int bond_debug_rlb_hash_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, bond_debug_rlb_hash_show, inode->i_private);
+}
+
+static const struct file_operations bond_debug_rlb_hash_fops = {
+	.owner		= THIS_MODULE,
+	.open		= bond_debug_rlb_hash_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 void bond_debug_register(struct bonding *bond)
 {
 	if (!bonding_debug_root)
@@ -25,6 +72,9 @@ void bond_debug_register(struct bonding
 			bond->dev->name);
 		return;
 	}
+
+	debugfs_create_file("rlb_hash_table", 0400, bond->debug_dir,
+				bond, &bond_debug_rlb_hash_fops);
 }

 void bond_debug_unregister(struct bonding *bond)



^ permalink raw reply

* Re: [PATCH 3/5] xfrm: Traffic Flow Confidentiality for IPv4 ESP
From: Herbert Xu @ 2010-12-03  7:34 UTC (permalink / raw)
  To: Martin Willi; +Cc: linux-crypto, netdev
In-Reply-To: <1291132155-31277-4-git-send-email-martin@strongswan.org>

On Tue, Nov 30, 2010 at 03:49:13PM +0000, Martin Willi wrote:
>
> +	if (skb->len >= tfcpadto) {
> +		clen = ALIGN(skb->len + 2, blksize);
> +	} else if (x->tfc.flags & XFRM_TFC_ESPV3 &&
> +		   x->props.mode == XFRM_MODE_TUNNEL) {
> +		/* ESPv3 TFC padding, append bytes to payload */
> +		tfclen = tfcpadto - skb->len;
> +		clen = ALIGN(skb->len + 2 + tfclen, blksize);
> +	} else {
> +		/* ESPv2 TFC padding. If we exceed the 255 byte maximum, use
> +		 * random padding to hide payload length as good as possible. */
> +		clen = ALIGN(skb->len + 2 + tfcpadto - skb->len, blksize);
> +		if (clen - skb->len - 2 > 255) {
> +			clen = ALIGN(skb->len + (u8)random32() + 2, blksize);
> +			if (clen - skb->len - 2 > 255)
> +				clen -= blksize;
> +		}

What is the basis of this random length padding?

Also, what happens when padto exceeds the MTU? Doesn't this
effectively disable PMTU-discovery?

I know that your last patch allows the padto to be set by PMTU.
But why would we ever want to use a padto that isn't clamped by
PMTU?

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH 3/5] xfrm: Traffic Flow Confidentiality for IPv4 ESP
From: Martin Willi @ 2010-12-03  8:32 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, netdev
In-Reply-To: <20101203073403.GA2292@gondor.apana.org.au>


> What is the basis of this random length padding?

Let assume a peer does not support ESPv3 padding, but we have to pad a
small packet with more than 255 bytes. We can't, the ESP padding length
field is limited to 255.
We could add 255 fixed bytes, but an eavesdropper could just subtract
the 255 bytes from all packets smaller than the boundary, rendering our
TFC efforts useless.
By inserting a random length padding in the range possible, the
eavesdropper knows that the packet has a length between "length" and
"length - 255", but can't estimated its exact size. I'm aware that this
is not optimal, but probably the best we can do(?).

> Also, what happens when padto exceeds the MTU? Doesn't this
> effectively disable PMTU-discovery?

Yes. An administrator setting a padto value larger than PMTU can
currently break PMTU discovery.

> I know that your last patch allows the padto to be set by PMTU.
> But why would we ever want to use a padto that isn't clamped by
> PMTU?

Probably never, valid point.

I'll add PMTU clamping to the next revision. We probably can drop the
PMTU flag then and just use USHRT_MAX instead. 

Thanks!
Martin

^ permalink raw reply

* Re: [PATCH 3/5] xfrm: Traffic Flow Confidentiality for IPv4 ESP
From: Herbert Xu @ 2010-12-03  8:39 UTC (permalink / raw)
  To: Martin Willi; +Cc: linux-crypto, netdev
In-Reply-To: <1291365175.1997.34.camel@martin>

On Fri, Dec 03, 2010 at 09:32:55AM +0100, Martin Willi wrote:
> 
> > What is the basis of this random length padding?
> 
> Let assume a peer does not support ESPv3 padding, but we have to pad a
> small packet with more than 255 bytes. We can't, the ESP padding length
> field is limited to 255.
> We could add 255 fixed bytes, but an eavesdropper could just subtract
> the 255 bytes from all packets smaller than the boundary, rendering our
> TFC efforts useless.
> By inserting a random length padding in the range possible, the
> eavesdropper knows that the packet has a length between "length" and
> "length - 255", but can't estimated its exact size. I'm aware that this
> is not optimal, but probably the best we can do(?).

I know why you want to do this, what I'm asking is do you have any
research behind this with regards to security (e.g., you're using an
insecure RNG to generate a value that is then used as the basis
for concealment)?

Has this scheme been discussed on a public forum somewhere?

> > I know that your last patch allows the padto to be set by PMTU.
> > But why would we ever want to use a padto that isn't clamped by
> > PMTU?
> 
> Probably never, valid point.
> 
> I'll add PMTU clamping to the next revision. We probably can drop the
> PMTU flag then and just use USHRT_MAX instead. 

Sounds good.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: multi bpf filter will impact performance?
From: Junchang Wang @ 2010-12-03  9:40 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Rui, netdev, Fenghua Yu
In-Reply-To: <1291176215.2856.383.camel@edumazet-laptop>

On Wed, Dec 1, 2010 at 12:03 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> But its rather important for performance that each cpu store packets
> into its own packet socket or ring buffer, to avoid false sharing
> slowdowns.

Hi Eric,
But the current situation is that a single socket (AF_PACKET for example)
can only create a ring buffer, meaning that multiple cores will compete
for passing data to user-space programs. Right?

>
> With such a setup (split packets to four cpus, then make sure one cpu
> deliver packets to one particular PACKET socket/ring buffer), it should
> really be fast enough.
>

Is there any patch or configuration? I'm preparing such a patch. I wonder
whether there's conflict.


Thanks.

--Junchang

^ permalink raw reply

* Question about __alloc_skb() speedup
From: Junchang Wang @ 2010-12-03 10:14 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev

Hi Eric,

I'm reading your patch (ec7d2f2cf3a1 __alloc_skb() speedup),
in which you prefetch skb and the shinfo part. I'm very
curious why we don't prefetch skb->data. It seems that will
help tx path a lot.

I added the following code

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 104f844..c60a808 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -222,6 +222,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 
 		child->fclone = SKB_FCLONE_UNAVAILABLE;
 	}
+	prefetchw(data);
+
 out:
 	return skb;
 nodata:

and the pktgen in my server (A Intel SR1625 server with two E5530 
4-core processors and a single ixgbe-based NIC) goes from 7.6Mpps to
8.4Mpps (64 byte), with 10% performance gain.

For rx path, I did experiments on both ixgbe and igb with pktgen+kute,
and there is no change in system performance.

welcome any suggestions and corrections.

Thanks.

--Junchang

^ permalink raw reply related

* Re: TCP: big bursts due to undos resulting from reordering
From: Lennart Schulte @ 2010-12-03 10:47 UTC (permalink / raw)
  To: John Heffner; +Cc: netdev@vger.kernel.org, Ilpo Järvinen
In-Reply-To: <AANLkTi=ptmSAAjiwmFyYx3QmcSXz2aZ7vn_Vf8+cLKW3@mail.gmail.com>

Hi John,
Thanks for your answer!

On 02.12.2010 18:55, John Heffner wrote:
> The problem that occurred, prior to this patch, was that cwnd was not
> able to effectively grow under persistent reordering.

Could you explain that deeper? What was the exact situation?
Do you have an example of when the smaller max_burst keep the cwnd down?
At the moment I can't think of a case.

Thanks,
Lennart

> On Thu, Dec 2, 2010 at 10:36 AM, Lennart Schulte
> <lennart.schulte@nets.rwth-aachen.de> wrote:
>> Hi John, hi Ilpo,
>>
>> at the moment I look on many TCP plots with reordering. When reordering
>> occurs there are some spurious retransmissions which are later undone by
>> e.g. DSACKs. This undo results in a very big burst of packets when
>> tp->reordering is high, since the function tcp_max_burst() returns
>> tp->reordering.
>>
>> This behavior was introduced because of a bug when using SACK instead of
>> Reno. The thread concerning this fix can be found at [1].
>>
>> Before the patch, which results from this thread, Linux has done a burst
>> of 3 packets and then slow started to the undone ssthresh value, which
>> is a much better way of handling an undo then it is after the patch.
>>
>> Also I patched a kernel to use the old max_burst value of 3 again to see
>> if it has any effect. Then I set up some virtual nodes and emulated a
>> network with netem as it was done in the thread.
>> The settings are:
>> - RTT 40ms
>> - no congestion, application sending rate 20 Mbps
>> - forward path: reordering rate 20%, reordering delay 20ms
>> - timestamps on
>>
>> Until now I have not found any evidence that the problem occurs (perhaps
>> because I don't get the settings right, since in the thread there is no
>> information concerning the settings for reordering and also the ones of
>> the sysctls).
>>
>> My problem is to understand why the patch was necessary and under what
>> circumstances SACK has a lower throughput so that it may be possible for
>> me to find another way of fixing this without introducing and old bug.
>> Since I can't figure it out on my own I hope to get some insights this
>> way :)
>>
>> Thanks,
>> Lennart Schulte
>>
>> [1] http://marc.info/?t=120728958000004&r=2&w=2

^ permalink raw reply

* Re: Question about __alloc_skb() speedup
From: Eric Dumazet @ 2010-12-03 10:50 UTC (permalink / raw)
  To: Junchang Wang; +Cc: netdev
In-Reply-To: <20101203101450.GA9573@Desktop-Junchang>

Le vendredi 03 décembre 2010 à 18:14 +0800, Junchang Wang a écrit :
> Hi Eric,
> 
> I'm reading your patch (ec7d2f2cf3a1 __alloc_skb() speedup),
> in which you prefetch skb and the shinfo part. I'm very
> curious why we don't prefetch skb->data. It seems that will
> help tx path a lot.
> 
> I added the following code
> 
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 104f844..c60a808 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -222,6 +222,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
>  
>  		child->fclone = SKB_FCLONE_UNAVAILABLE;
>  	}
> +	prefetchw(data);
> +
>  out:
>  	return skb;
>  nodata:
> 
> and the pktgen in my server (A Intel SR1625 server with two E5530 
> 4-core processors and a single ixgbe-based NIC) goes from 7.6Mpps to
> 8.4Mpps (64 byte), with 10% performance gain.
> 
> For rx path, I did experiments on both ixgbe and igb with pktgen+kute,
> and there is no change in system performance.
> 
> welcome any suggestions and corrections.
> 
> Thanks.

This is because __alloc_skb() is generic :

We dont know if the skb->data is going to be used right after or not at
all.

For example, NIC drivers call __alloc_skb() to refill their RX ring
buffer. There is no gain to prefetch data in this case since the data is
going to be written by the NIC hardware. The reverse would be needed
actually : ask to local cpu to evict data from its cache, so that device
can DMA it faster (less bus transactions)

By the way, adding prefetchw() right before the "return skb;" is
probably not very useful. You can certainly try to add the prefetchw()
in pktgen itself, since you know for sure you are going to write the
data.

I dont understand your 10% speedup because pktgen actually uses
__netdev_alloc_skb(), so it calls skb_reserve(skb, NET_SKB_PAD) : your
prefetchw is bringing a cache line that wont be used at all by pktgen.

I would say 10% sounds highly suspect to me...




^ permalink raw reply

* TSO/GRO/LRO/somethingO breaks LVS on 2.6.36
From: Simon Kirby @ 2010-12-03 10:34 UTC (permalink / raw)
  To: Eric Dumazet, netdev

Hello!

We upgraded some LVS (DR) servers from 2.6.35 to 2.6.36 on tg3 cards
(partno(BCM95721) rev 4201) with VLAN tags in use, to think that
everything looked great, but in fact...

LVS was receiving magically-merged TCP packets which it tried to forward
on to the real server, only to get annoyed at itself for trying to
forward a packet bigger than the device MTU:

IP A.47376 > B.529: . 175488:176936(1448) ack 1 win 92 <nop,nop,timestamp 52737308 29656081>
IP A.47376 > B.529: . 176936:179832(2896) ack 1 win 92 <nop,nop,timestamp 52737325 29656098>
IP B > A: ICMP B unreachable - need to frag (mtu 1500), length 556

This caused packet loss for any merged frames, which caused abysmal
performance for uploads via the LVS server.  Local performance to or
from the box is still fine, because the stack doesn't care, only the
forwarding part of LVS is running into the problem.

Furthermore, disabling _everything_ reported by ethtool -k doesn't seem
to change the result, even if I down/up the interface after, and even if
I try on every single interface including the VLANned ones.  This seems
to be another bug.  Reverting to 2.6.35 makes it all work again.

Possibly related to commit 7fe876af921d1d2bc8353e0062c10ff35e902653

So how should this be fixed?  Should LVS be taught to fragment, or must
we disable the merging in this case?  It seems like it would work well if
the sending side could do the same offload in reverse, but I'm not sure
if that would be possible.

Simon-

^ permalink raw reply

* Re: [RFC PATCH v1] iproute2: add IFLA_TC support to 'ip link'
From: jamal @ 2010-12-03 11:06 UTC (permalink / raw)
  To: John Fastabend
  Cc: shemminger@vyatta.com, netdev@vger.kernel.org,
	tgraf@infradead.org, eric.dumazet@gmail.com, davem@davemloft.net
In-Reply-To: <4CF7F8B4.4060807@intel.com>

On Thu, 2010-12-02 at 11:51 -0800, John Fastabend wrote:
> On 12/2/2010 2:40 AM, jamal wrote:


> I viewed the HW QOS as L2 link attributes more than a queuing discipline per se.
> Plus 'ip link' is already used to set things outside of ip. 
> For example 'txqueuelen' and 'vf x'.

the vf one maybe borderline-ok txquelen is probably inherited from
ifconfig (and not sure a single queue a scheduler qualifies)


> However thinking about this a bit more qdisc support seems cleaner. 
> For one we can configure QOS policies per class with Qdisc_class_ops. 
> And then also aggregate statistics with dump_stats. I would avoid the 
> "hardware-kinda-8021q-sched" name though to account for schedulers that 
> may not be 802.1Q compliant maybe 'mclass-sched' for multi-class scheduler. 

Typically the scheduler would be a very familiar one implemented
per-spec by many vendors and will have a name acceptable by all.
So pick an appropriate noun so the user expectation matches it.

> I'll look into this. Thanks for the suggestion!

> 
> On egress the skb priority is mapped to a class which is associated with a
> range of queues (qoffset:qoffset + qcount). 
> In the 802.1Q case this queue range is mapped to the 802.1Qp 
> traffic class in hardware. So the hardware traffic class is mapped 1-1 
> with the software class. Additionally in software the VLAN egress mapping
> is used to map the skb priority to the 802.1Q priority. Here I expect user
> policies to configure this to get a consistent mapping. On ingress the 
> skb priority is set using the 802.1Q ingress mapping. This case is 
> something a userspace policy could configure if egress/ingress mappings
> should be symmetric.
> 

Sounds sensible. 

> In the simpler case of hardware rate limiting (not 802.1Q) this is not
> really a concern at all. With this mechanism we can identify traffic 
> and push it to the correct queues that are grouped into a rate limited class.

Ok, so you can do rate control as well?

> If there are egress/ingress mappings then those will apply skb priority tags 
> on egress and the correct skb priority on ingress.

Curious how you would do this in a rate controlled environment. EX: on
egress, do you use whatever skb prio you get to map to a specific rate
queue in h/ware? Note: skb prio has a strict priority scheduling
semantics so a 1-1 mapping doesnt sound reasonable..

> Currently everything works reasonably well with this scheme and the mq qdisc.
>  The mq qdisc uses pfifo and the driver then pauses the queues as needed. 
> Using the enhanced transmission selection algorithm (ETS - 802.1Qaz pre-standard)
>  in hardware we see variations from expected bandwidth around +-5% with TCP/UDP. 
> Instrumenting HW rate limiters gives similar variations. I tested this is with 
> ixgbe and the 82599 device.
> 
> Bit long winded but hopefully that answers your question.

I am curious about the rate based scheme - and i hope you are looking at
a different qdisc for that?

cheers,
jamal


^ permalink raw reply

* Re: TSO/GRO/LRO/somethingO breaks LVS on 2.6.36
From: Eric Dumazet @ 2010-12-03 11:29 UTC (permalink / raw)
  To: Simon Kirby; +Cc: netdev, Simon Horman
In-Reply-To: <20101203103447.GA29714@hostway.ca>

Le vendredi 03 décembre 2010 à 02:34 -0800, Simon Kirby a écrit :
> Hello!
> 
> We upgraded some LVS (DR) servers from 2.6.35 to 2.6.36 on tg3 cards
> (partno(BCM95721) rev 4201) with VLAN tags in use, to think that
> everything looked great, but in fact...
> 
> LVS was receiving magically-merged TCP packets which it tried to forward
> on to the real server, only to get annoyed at itself for trying to
> forward a packet bigger than the device MTU:
> 
> IP A.47376 > B.529: . 175488:176936(1448) ack 1 win 92 <nop,nop,timestamp 52737308 29656081>
> IP A.47376 > B.529: . 176936:179832(2896) ack 1 win 92 <nop,nop,timestamp 52737325 29656098>
> IP B > A: ICMP B unreachable - need to frag (mtu 1500), length 556
> 

Hi Simon

This is a tcpdump on A ?
Could you take it also on B ?

tcpdump displays large buffers, but they should be split (of course)
when sent on wire.

> This caused packet loss for any merged frames, which caused abysmal
> performance for uploads via the LVS server.  Local performance to or
> from the box is still fine, because the stack doesn't care, only the
> forwarding part of LVS is running into the problem.
> 
> Furthermore, disabling _everything_ reported by ethtool -k doesn't seem
> to change the result, even if I down/up the interface after, and even if
> I try on every single interface including the VLANned ones.  This seems
> to be another bug.  Reverting to 2.6.35 makes it all work again.
> 
> Possibly related to commit 7fe876af921d1d2bc8353e0062c10ff35e902653
> 
> So how should this be fixed?  Should LVS be taught to fragment, or must
> we disable the merging in this case?  It seems like it would work well if
> the sending side could do the same offload in reverse, but I'm not sure
> if that would be possible.
> 
> Simon-


I believe Simon Horman has some patches for GRO and LVS.

Please send the results of "ethtool -k eth0" on all your nics / vlans ?

For TSO, I am not sure why and where it could matter...




^ permalink raw reply

* Re: TSO/GRO/LRO/somethingO breaks LVS on 2.6.36
From: Simon Horman @ 2010-12-03 12:36 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Simon Kirby, netdev
In-Reply-To: <1291375743.2897.141.camel@edumazet-laptop>

On Fri, Dec 03, 2010 at 12:29:03PM +0100, Eric Dumazet wrote:
> Le vendredi 03 décembre 2010 à 02:34 -0800, Simon Kirby a écrit :
> > Hello!
> > 
> > We upgraded some LVS (DR) servers from 2.6.35 to 2.6.36 on tg3 cards
> > (partno(BCM95721) rev 4201) with VLAN tags in use, to think that
> > everything looked great, but in fact...
> > 
> > LVS was receiving magically-merged TCP packets which it tried to forward
> > on to the real server, only to get annoyed at itself for trying to
> > forward a packet bigger than the device MTU:
> > 
> > IP A.47376 > B.529: . 175488:176936(1448) ack 1 win 92 <nop,nop,timestamp 52737308 29656081>
> > IP A.47376 > B.529: . 176936:179832(2896) ack 1 win 92 <nop,nop,timestamp 52737325 29656098>
> > IP B > A: ICMP B unreachable - need to frag (mtu 1500), length 556
> > 
> 
> Hi Simon
> 
> This is a tcpdump on A ?
> Could you take it also on B ?
> 
> tcpdump displays large buffers, but they should be split (of course)
> when sent on wire.
> 
> > This caused packet loss for any merged frames, which caused abysmal
> > performance for uploads via the LVS server.  Local performance to or
> > from the box is still fine, because the stack doesn't care, only the
> > forwarding part of LVS is running into the problem.
> > 
> > Furthermore, disabling _everything_ reported by ethtool -k doesn't seem
> > to change the result, even if I down/up the interface after, and even if
> > I try on every single interface including the VLANned ones.  This seems
> > to be another bug.  Reverting to 2.6.35 makes it all work again.
> > 
> > Possibly related to commit 7fe876af921d1d2bc8353e0062c10ff35e902653
> > 
> > So how should this be fixed?  Should LVS be taught to fragment, or must
> > we disable the merging in this case?  It seems like it would work well if
> > the sending side could do the same offload in reverse, but I'm not sure
> > if that would be possible.
> > 
> > Simon-
> 
> 
> I believe Simon Horman has some patches for GRO and LVS.
> 
> Please send the results of "ethtool -k eth0" on all your nics / vlans ?
> 
> For TSO, I am not sure why and where it could matter...

There is a patch to teach LVS how to cope with GRO in nf-next-2.6
and I expect it to be included in 2.6.38. The patch is "ipvs: allow
transmit of GRO aggregated skbs" and perhaps it should be considered
for 2.6.37 and stable. In general the work around is to disable GRO.

The patch does not resolve the incompatibility of LVS with LRO.
The work around there is to disable LRO. I'm not entirely sure
how to teach LVS to disable LRO automatically, or if its desirable.

Simon, you mention that you disabled everything with ethtool, but the
tcpdump above shows a 2896 byte packet, which seems that GRO (or LRO?) is
active. So perhaps as you speculate that is a bug

I will prepare a backport of the "ipvs: allow transmit of GRO aggregated
skbs" patch to v2.6.36 and post it shortly.  Testing to see if that
resolves the problem that you are seeing would probably be a good start.


^ permalink raw reply

* [PATCH 0/2] New jhash function
From: Jozsef Kadlecsik @ 2010-12-03 12:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, netfilter-devel, Linus Torvalds, Rusty Russell,
	Jozsef Kadlecsik
In-Reply-To: <201011271401.22773.rusty@rustcorp.com.au>

Hi,

The current jhash.h implements the lookup2() hash function by Bob Jenkins. 
However, lookup2() is outdated as Bob wrote a new hash function called 
lookup3(). There is a longer comparison of those two and other hash
functions at http://burtleburtle.net/bob/hash/doobs.html.

Please consider applying the following patches.

Speed

I wrote a small benchmark program to compare jhash2 and jhash3 (you can
download it from http://www.kfki.hu/~kadlec/sw/netfilter/jhash23.tgz).
On a machine with Core2 Duo and compiled with -O2, the ratio of the execution
time for the byte variants of the hash functions were (in parens the different
key sizes):

jhash2/jhash3 (4 bytes): 1.587518
jhash2/jhash3 (8 bytes): 1.282824
jhash2/jhash3 (12 bytes): 2.349628
jhash2/jhash3 (16 bytes): 1.466988
jhash2/jhash3 (32 bytes): 1.501063
jhash2/jhash3 (64 bytes): 1.587527
jhash2/jhash3 (128 bytes): 1.628037
jhash2/jhash3 (256 bytes): 1.648318

Similarly, for the word variants

jhash2/jhash3 (1 words): 1.300904
jhash2/jhash3 (2 words): 1.316108
jhash2/jhash3 (3 words): 2.249708
jhash2/jhash3 (4 words): 1.460192
jhash2/jhash3 (8 words): 1.501438
jhash2/jhash3 (16 words): 1.558039
jhash2/jhash3 (32 words): 1.520082
jhash2/jhash3 (64 words): 1.528347

Sizes

When compiling just the byte variants the sizes are

   text    data     bss     dec     hex filename
    661       0       0     661     295 jhashb2.o
    441       0       0     441     1b9 jhashb3.o

and for the word variants

   text    data     bss     dec     hex filename
    354       0       0     354     162 jhashw2.o
    248       0       0     248      f8 jhashw3.o

I compiled the kernel with "allyesconfig", in three variants: jhash2, jhash3 and
jhash3 un-inlined

   text    data     bss     dec     hex filename
69297477        11282083        35904032        116483592       6f16608 vmlinux.jhash2
69293829        11282083        35903728        116479640       6f15698 vmlinux.jhash3
69288578        11282083        35902336        116472997       6f13ca5 vmlinux.jhash3-uninlined

With jhash3 we can gain 3.6k and un-inlining shrinks the code with an additional
5.2k. In the patch I left jhash(3) inlined.

Uniformity

According to Bob Jenkins, lookup3() mixes better than lookup2(): it passes
the check that every input bit changes every output bit 50% of the time, while
lookup2() failed it. In order to verify it I added jhash3 to the cttest program,
which tests hash functions with (artifical, worst case) netfilter conntrack data
and calculates the statistics (chi-square, probability of longest bucket, etc).
You can find the program and the results here:
http://www.kfki.hu/~kadlec/sw/netfilter/ct3/ - to sum up, lookup3() produces
uniform key values and no weakness could be spotted.

Many thanks to Eric Dumazet for his thorough reviewing.

Dave applied the first patch to net-next-2.6.

Jozsef Kadlecsik (2):
  Remove calls to jhash internals
  The new jhash implementation

 include/linux/jhash.h            |  183 ++++++++++++++++++++++----------------
 net/ipv6/inet6_connection_sock.c |   18 ++--
 net/ipv6/reassembly.c            |   36 ++++----
 3 files changed, 129 insertions(+), 108 deletions(-)

^ permalink raw reply

* [PATCH 1/2] Remove calls to jhash internals
From: Jozsef Kadlecsik @ 2010-12-03 12:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, netfilter-devel, Linus Torvalds, Rusty Russell,
	Jozsef Kadlecsik
In-Reply-To: <1291379941-31565-1-git-send-email-kadlec@blackhole.kfki.hu>

Because the jhash implementation changes, replace the calls to the jhash
internal macros with calls to the jhash functions.
---
 net/ipv6/inet6_connection_sock.c |   18 ++++++++----------
 net/ipv6/reassembly.c            |   36 ++++++++++++++++--------------------
 2 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 8a16280..861d252 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -60,18 +60,16 @@ EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
 static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
 			   const u32 rnd, const u16 synq_hsize)
 {
-	u32 a = (__force u32)raddr->s6_addr32[0];
-	u32 b = (__force u32)raddr->s6_addr32[1];
-	u32 c = (__force u32)raddr->s6_addr32[2];
-
-	a += JHASH_GOLDEN_RATIO;
-	b += JHASH_GOLDEN_RATIO;
-	c += rnd;
-	__jhash_mix(a, b, c);
-
-	a += (__force u32)raddr->s6_addr32[3];
-	b += (__force u32)rport;
-	__jhash_mix(a, b, c);
+	u32 c;
+
+	c = jhash_3words((__force u32)raddr->s6_addr32[0],
+			 (__force u32)raddr->s6_addr32[1],
+			 (__force u32)raddr->s6_addr32[2],
+			 rnd);
+
+	c = jhash_2words((__force u32)raddr->s6_addr32[3],
+			 (__force u32)rport,
+			 c);
 
 	return c & (synq_hsize - 1);
 }
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index c7ba314..5e57490 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -104,26 +104,22 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
 unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr,
 			     const struct in6_addr *daddr, u32 rnd)
 {
-	u32 a, b, c;
-
-	a = (__force u32)saddr->s6_addr32[0];
-	b = (__force u32)saddr->s6_addr32[1];
-	c = (__force u32)saddr->s6_addr32[2];
-
-	a += JHASH_GOLDEN_RATIO;
-	b += JHASH_GOLDEN_RATIO;
-	c += rnd;
-	__jhash_mix(a, b, c);
-
-	a += (__force u32)saddr->s6_addr32[3];
-	b += (__force u32)daddr->s6_addr32[0];
-	c += (__force u32)daddr->s6_addr32[1];
-	__jhash_mix(a, b, c);
-
-	a += (__force u32)daddr->s6_addr32[2];
-	b += (__force u32)daddr->s6_addr32[3];
-	c += (__force u32)id;
-	__jhash_mix(a, b, c);
+	u32 c;
+
+	c = jhash_3words((__force u32)saddr->s6_addr32[0],
+			 (__force u32)saddr->s6_addr32[1],
+			 (__force u32)saddr->s6_addr32[2],
+			 rnd);
+
+	c = jhash_3words((__force u32)saddr->s6_addr32[3],
+			 (__force u32)daddr->s6_addr32[0],
+			 (__force u32)daddr->s6_addr32[1],
+			 c);
+
+	c =  jhash_3words((__force u32)daddr->s6_addr32[2],
+			  (__force u32)daddr->s6_addr32[3],
+			  (__force u32)id,
+			  c);
 
 	return c & (INETFRAGS_HASHSZ - 1);
 }
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 2/2] The new jhash implementation
From: Jozsef Kadlecsik @ 2010-12-03 12:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, netfilter-devel, Linus Torvalds, Rusty Russell,
	Jozsef Kadlecsik
In-Reply-To: <1291379941-31565-2-git-send-email-kadlec@blackhole.kfki.hu>

The current jhash.h implements the lookup2() hash function by Bob Jenkins.
However, lookup2() is outdated as Bob wrote a new hash function called
lookup3(). The patch replaces the lookup2() implementation of the 'jhash*'
functions with that of lookup3().

You can read a longer comparison of the two and other hash functions at
http://burtleburtle.net/bob/hash/doobs.html.
---
 include/linux/jhash.h |  183 ++++++++++++++++++++++++++++---------------------
 1 files changed, 105 insertions(+), 78 deletions(-)

diff --git a/include/linux/jhash.h b/include/linux/jhash.h
index ced1159..47cb09e 100644
--- a/include/linux/jhash.h
+++ b/include/linux/jhash.h
@@ -3,129 +3,156 @@
 
 /* jhash.h: Jenkins hash support.
  *
- * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
  *
  * http://burtleburtle.net/bob/hash/
  *
  * These are the credits from Bob's sources:
  *
- * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
- * hash(), hash2(), hash3, and mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose.  It has no warranty.
+ * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * These are functions for producing 32-bit hashes for hash table lookup.
+ * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+ * are externally useful functions.  Routines to test the hash are included
+ * if SELF_TEST is defined.  You can use this free for any purpose.  It's in
+ * the public domain.  It has no warranty.
+ *
+ * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
  *
  * I've modified Bob's hash to be useful in the Linux kernel, and
- * any bugs present are surely my fault.  -DaveM
+ * any bugs present are my fault.
+ * Jozsef
  */
+#include <linux/bitops.h>
+#include <linux/unaligned/packed_struct.h>
+
+/* Best hash sizes are of power of two */
+#define jhash_size(n)   ((u32)1<<(n))
+/* Mask the hash value, i.e (value & jhash_mask(n)) instead of (value % n) */
+#define jhash_mask(n)   (jhash_size(n)-1)
+
+/* __jhash_mix -- mix 3 32-bit values reversibly. */
+#define __jhash_mix(a, b, c)			\
+{						\
+	a -= c;  a ^= rol32(c, 4);  c += b;	\
+	b -= a;  b ^= rol32(a, 6);  a += c;	\
+	c -= b;  c ^= rol32(b, 8);  b += a;	\
+	a -= c;  a ^= rol32(c, 16); c += b;	\
+	b -= a;  b ^= rol32(a, 19); a += c;	\
+	c -= b;  c ^= rol32(b, 4);  b += a;	\
+}
 
-/* NOTE: Arguments are modified. */
-#define __jhash_mix(a, b, c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<<8); \
-  c -= a; c -= b; c ^= (b>>13); \
-  a -= b; a -= c; a ^= (c>>12);  \
-  b -= c; b -= a; b ^= (a<<16); \
-  c -= a; c -= b; c ^= (b>>5); \
-  a -= b; a -= c; a ^= (c>>3);  \
-  b -= c; b -= a; b ^= (a<<10); \
-  c -= a; c -= b; c ^= (b>>15); \
+/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
+#define __jhash_final(a, b, c)			\
+{						\
+	c ^= b; c -= rol32(b, 14);		\
+	a ^= c; a -= rol32(c, 11);		\
+	b ^= a; b -= rol32(a, 25);		\
+	c ^= b; c -= rol32(b, 16);		\
+	a ^= c; a -= rol32(c, 4);		\
+	b ^= a; b -= rol32(a, 14);		\
+	c ^= b; c -= rol32(b, 24);		\
 }
 
-/* The golden ration: an arbitrary value */
-#define JHASH_GOLDEN_RATIO	0x9e3779b9
+/* An arbitrary initial parameter */
+#define JHASH_INITVAL		0xdeadbeef
 
-/* The most generic version, hashes an arbitrary sequence
- * of bytes.  No alignment or length assumptions are made about
- * the input key.
+/* jhash - hash an arbitrary key
+ * @k: sequence of bytes as key
+ * @length: the length of the key
+ * @initval: the previous hash, or an arbitray value
+ *
+ * The generic version, hashes an arbitrary sequence of bytes.
+ * No alignment or length assumptions are made about the input key.
+ *
+ * Returns the hash value of the key. The result depends on endianness.
  */
 static inline u32 jhash(const void *key, u32 length, u32 initval)
 {
-	u32 a, b, c, len;
+	u32 a, b, c;
 	const u8 *k = key;
 
-	len = length;
-	a = b = JHASH_GOLDEN_RATIO;
-	c = initval;
-
-	while (len >= 12) {
-		a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
-		b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
-		c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
-
-		__jhash_mix(a,b,c);
+	/* Set up the internal state */
+	a = b = c = JHASH_INITVAL + length + initval;
 
+	/* All but the last block: affect some 32 bits of (a,b,c) */
+	while (length > 12) {
+		a += __get_unaligned_cpu32(k);
+		b += __get_unaligned_cpu32(k + 4);
+		c += __get_unaligned_cpu32(k + 8);
+		__jhash_mix(a, b, c);
+		length -= 12;
 		k += 12;
-		len -= 12;
 	}
-
-	c += length;
-	switch (len) {
-	case 11: c += ((u32)k[10]<<24);
-	case 10: c += ((u32)k[9]<<16);
-	case 9 : c += ((u32)k[8]<<8);
-	case 8 : b += ((u32)k[7]<<24);
-	case 7 : b += ((u32)k[6]<<16);
-	case 6 : b += ((u32)k[5]<<8);
-	case 5 : b += k[4];
-	case 4 : a += ((u32)k[3]<<24);
-	case 3 : a += ((u32)k[2]<<16);
-	case 2 : a += ((u32)k[1]<<8);
-	case 1 : a += k[0];
-	};
-
-	__jhash_mix(a,b,c);
+	/* Last block: affect all 32 bits of (c) */
+	/* All the case statements fall through */
+	switch (length) {
+	case 12: c += (u32)k[11]<<24;
+	case 11: c += (u32)k[10]<<16;
+	case 10: c += (u32)k[9]<<8;
+	case 9:  c += k[8];
+	case 8:  b += (u32)k[7]<<24;
+	case 7:  b += (u32)k[6]<<16;
+	case 6:  b += (u32)k[5]<<8;
+	case 5:  b += k[4];
+	case 4:  a += (u32)k[3]<<24;
+	case 3:  a += (u32)k[2]<<16;
+	case 2:  a += (u32)k[1]<<8;
+	case 1:  a += k[0];
+		 __jhash_final(a, b, c);
+	case 0: /* Nothing left to add */
+		break;
+	}
 
 	return c;
 }
 
-/* A special optimized version that handles 1 or more of u32s.
- * The length parameter here is the number of u32s in the key.
+/* jhash2 - hash an array of u32's
+ * @k: the key which must be an array of u32's
+ * @length: the number of u32's in the key
+ * @initval: the previous hash, or an arbitray value
+ *
+ * Returns the hash value of the key.
  */
 static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
 {
-	u32 a, b, c, len;
+	u32 a, b, c;
 
-	a = b = JHASH_GOLDEN_RATIO;
-	c = initval;
-	len = length;
+	/* Set up the internal state */
+	a = b = c = JHASH_INITVAL + (length<<2) + initval;
 
-	while (len >= 3) {
+	/* Handle most of the key */
+	while (length > 3) {
 		a += k[0];
 		b += k[1];
 		c += k[2];
 		__jhash_mix(a, b, c);
-		k += 3; len -= 3;
+		length -= 3;
+		k += 3;
 	}
 
-	c += length * 4;
-
-	switch (len) {
-	case 2 : b += k[1];
-	case 1 : a += k[0];
-	};
-
-	__jhash_mix(a,b,c);
+	/* Handle the last 3 u32's: all the case statements fall through */
+	switch (length) {
+	case 3: c += k[2];
+	case 2: b += k[1];
+	case 1: a += k[0];
+		__jhash_final(a, b, c);
+	case 0:	/* Nothing left to add */
+		break;
+	}
 
 	return c;
 }
 
 
-/* A special ultra-optimized versions that knows they are hashing exactly
- * 3, 2 or 1 word(s).
- *
- * NOTE: In particular the "c += length; __jhash_mix(a,b,c);" normally
- *       done at the end is not done here.
- */
+/* jhash_3words - hash exactly 3, 2 or 1 word(s) */
 static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
 {
-	a += JHASH_GOLDEN_RATIO;
-	b += JHASH_GOLDEN_RATIO;
+	a += JHASH_INITVAL;
+	b += JHASH_INITVAL;
 	c += initval;
 
-	__jhash_mix(a, b, c);
+	__jhash_final(a, b, c);
 
 	return c;
 }
-- 
1.7.0.4


^ permalink raw reply related

* Re: TSO/GRO/LRO/somethingO breaks LVS on 2.6.36
From: Simon Horman @ 2010-12-03 12:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Simon Kirby, netdev, lvs-devel, Julian Anastasov, Herbert Xu
In-Reply-To: <20101203123617.GA6993@verge.net.au>

[ CCed lvs-devel, Julian Anastasov and Herbert Xu ]

On Fri, Dec 03, 2010 at 09:36:19PM +0900, Simon Horman wrote:
> On Fri, Dec 03, 2010 at 12:29:03PM +0100, Eric Dumazet wrote:
> > Le vendredi 03 décembre 2010 à 02:34 -0800, Simon Kirby a écrit :
> > > Hello!
> > > 
> > > We upgraded some LVS (DR) servers from 2.6.35 to 2.6.36 on tg3 cards
> > > (partno(BCM95721) rev 4201) with VLAN tags in use, to think that
> > > everything looked great, but in fact...
> > > 
> > > LVS was receiving magically-merged TCP packets which it tried to forward
> > > on to the real server, only to get annoyed at itself for trying to
> > > forward a packet bigger than the device MTU:
> > > 
> > > IP A.47376 > B.529: . 175488:176936(1448) ack 1 win 92 <nop,nop,timestamp 52737308 29656081>
> > > IP A.47376 > B.529: . 176936:179832(2896) ack 1 win 92 <nop,nop,timestamp 52737325 29656098>
> > > IP B > A: ICMP B unreachable - need to frag (mtu 1500), length 556
> > > 
> > 
> > Hi Simon
> > 
> > This is a tcpdump on A ?
> > Could you take it also on B ?
> > 
> > tcpdump displays large buffers, but they should be split (of course)
> > when sent on wire.
> > 
> > > This caused packet loss for any merged frames, which caused abysmal
> > > performance for uploads via the LVS server.  Local performance to or
> > > from the box is still fine, because the stack doesn't care, only the
> > > forwarding part of LVS is running into the problem.
> > > 
> > > Furthermore, disabling _everything_ reported by ethtool -k doesn't seem
> > > to change the result, even if I down/up the interface after, and even if
> > > I try on every single interface including the VLANned ones.  This seems
> > > to be another bug.  Reverting to 2.6.35 makes it all work again.
> > > 
> > > Possibly related to commit 7fe876af921d1d2bc8353e0062c10ff35e902653
> > > 
> > > So how should this be fixed?  Should LVS be taught to fragment, or must
> > > we disable the merging in this case?  It seems like it would work well if
> > > the sending side could do the same offload in reverse, but I'm not sure
> > > if that would be possible.
> > > 
> > > Simon-
> > 
> > 
> > I believe Simon Horman has some patches for GRO and LVS.
> > 
> > Please send the results of "ethtool -k eth0" on all your nics / vlans ?
> > 
> > For TSO, I am not sure why and where it could matter...
> 
> There is a patch to teach LVS how to cope with GRO in nf-next-2.6
> and I expect it to be included in 2.6.38. The patch is "ipvs: allow
> transmit of GRO aggregated skbs" and perhaps it should be considered
> for 2.6.37 and stable. In general the work around is to disable GRO.
> 
> The patch does not resolve the incompatibility of LVS with LRO.
> The work around there is to disable LRO. I'm not entirely sure
> how to teach LVS to disable LRO automatically, or if its desirable.
> 
> Simon, you mention that you disabled everything with ethtool, but the
> tcpdump above shows a 2896 byte packet, which seems that GRO (or LRO?) is
> active. So perhaps as you speculate that is a bug
> 
> I will prepare a backport of the "ipvs: allow transmit of GRO aggregated
> skbs" patch to v2.6.36 and post it shortly.  Testing to see if that
> resolves the problem that you are seeing would probably be a good start.

Here is the patch for v2.6.36.

From: Simon Horman <horms@verge.net.au>

ipvs: allow transmit of GRO aggregated skbs

Attempt at allowing LVS to transmit skbs of greater than MTU length that
have been aggregated by GRO and can thus be deaggregated by GSO.

Cc: Julian Anastasov <ja@ssi.bg>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Simon Horman <horms@verge.net.au>

---
 net/netfilter/ipvs/ip_vs_xmit.c |   25 +++++++++++++++----------
 1 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 49df6be..577f502 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -247,7 +247,8 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	/* MTU checking */
 	mtu = dst_mtu(&rt->dst);
-	if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF))) {
+	if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF)) &&
+	    !skb_is_gso(skb)) {
 		ip_rt_put(rt);
 		icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
 		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
@@ -311,7 +312,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	/* MTU checking */
 	mtu = dst_mtu(&rt->dst);
-	if (skb->len > mtu) {
+	if (skb->len > mtu && !skb_is_gso(skb)) {
 		dst_release(&rt->dst);
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
 		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
@@ -408,7 +409,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	/* MTU checking */
 	mtu = dst_mtu(&rt->dst);
-	if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF))) {
+	if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF)) &&
+	    !skb_is_gso(skb)) {
 		ip_rt_put(rt);
 		icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
 		IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit(): frag needed for");
@@ -486,7 +488,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	/* MTU checking */
 	mtu = dst_mtu(&rt->dst);
-	if (skb->len > mtu) {
+	if (skb->len > mtu && !skb_is_gso(skb)) {
 		dst_release(&rt->dst);
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
 		IP_VS_DBG_RL_PKT(0, pp, skb, 0,
@@ -597,8 +599,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	df |= (old_iph->frag_off & htons(IP_DF));
 
-	if ((old_iph->frag_off & htons(IP_DF))
-	    && mtu < ntohs(old_iph->tot_len)) {
+	if ((old_iph->frag_off & htons(IP_DF) &&
+	    mtu < ntohs(old_iph->tot_len) && !skb_is_gso(skb))) {
 		icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
 		ip_rt_put(rt);
 		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
@@ -707,7 +709,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if (skb_dst(skb))
 		skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
-	if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) {
+	if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) &&
+	    !skb_is_gso(skb)) {
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
 		dst_release(&rt->dst);
 		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
@@ -796,7 +799,8 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	/* MTU checking */
 	mtu = dst_mtu(&rt->dst);
-	if ((iph->frag_off & htons(IP_DF)) && skb->len > mtu) {
+	if ((iph->frag_off & htons(IP_DF)) && skb->len > mtu &&
+	    !skb_is_gso(skb)) {
 		icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
 		ip_rt_put(rt);
 		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
@@ -924,7 +928,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	/* MTU checking */
 	mtu = dst_mtu(&rt->dst);
-	if ((skb->len > mtu) && (ip_hdr(skb)->frag_off & htons(IP_DF))) {
+	if ((skb->len > mtu) && (ip_hdr(skb)->frag_off & htons(IP_DF)) &&
+	    !skb_is_gso(skb)) {
 		ip_rt_put(rt);
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
 		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
@@ -999,7 +1004,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	/* MTU checking */
 	mtu = dst_mtu(&rt->dst);
-	if (skb->len > mtu) {
+	if (skb->len > mtu && !skb_is_gso(skb)) {
 		dst_release(&rt->dst);
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
 		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
-- 
1.7.2.3


^ permalink raw reply related

* Re: PCI: make pci_restore_state return void
From: Mauro Carvalho Chehab @ 2010-12-03 13:08 UTC (permalink / raw)
  To: Jon Mason
  Cc: Jesse Barnes, linux-pci, Jonathan Corbet, linux-media,
	Andrew Gallatin, Brice Goglin, netdev,
	Solarflare linux maintainers, Steve Hodgson, Ben Hutchings,
	Stephen Hemminger, Ivo van Doorn, Gertjan van Wingerde,
	linux-wireless, Brian King, Anil Ravindranath, linux-scsi,
	Jaya Kumar, boyod.yang
In-Reply-To: <1291160606-31494-1-git-send-email-jon.mason@exar.com>

Em 30-11-2010 21:43, Jon Mason escreveu:
> pci_restore_state only ever returns 0, thus there is no benefit in
> having it return any value.  Also, a large majority of the callers do
> not check the return code of pci_restore_state.  Make the
> pci_restore_state a void return and avoid the overhead.
> 
> Signed-off-by: Jon Mason <jon.mason@exar.com>
> ---
>  drivers/media/video/cafe_ccic.c         |    4 +---

Seems ok to me.

Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>

>  drivers/net/myri10ge/myri10ge.c         |    4 +---
>  drivers/net/sfc/falcon.c                |   25 +++++--------------------
>  drivers/net/skge.c                      |    4 +---
>  drivers/net/sky2.c                      |    5 +----
>  drivers/net/wireless/rt2x00/rt2x00pci.c |    4 ++--
>  drivers/pci/pci-driver.c                |    3 ++-
>  drivers/pci/pci.c                       |    7 ++-----
>  drivers/scsi/ipr.c                      |    8 +-------
>  drivers/scsi/pmcraid.c                  |    7 +------
>  drivers/staging/sm7xx/smtcfb.c          |    2 +-
>  include/linux/pci.h                     |    8 +++-----
>  sound/pci/cs5535audio/cs5535audio_pm.c  |    7 +------
>  13 files changed, 22 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
> index 2934770..3e653f3 100644
> --- a/drivers/media/video/cafe_ccic.c
> +++ b/drivers/media/video/cafe_ccic.c
> @@ -2186,9 +2186,7 @@ static int cafe_pci_resume(struct pci_dev *pdev)
>  	struct cafe_camera *cam = to_cam(v4l2_dev);
>  	int ret = 0;
>  
> -	ret = pci_restore_state(pdev);
> -	if (ret)
> -		return ret;
> +	pci_restore_state(pdev);
>  	ret = pci_enable_device(pdev);
>  
>  	if (ret) {
> diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
> index 8524cc4..d3c4a37 100644
> --- a/drivers/net/myri10ge/myri10ge.c
> +++ b/drivers/net/myri10ge/myri10ge.c
> @@ -3403,9 +3403,7 @@ static int myri10ge_resume(struct pci_dev *pdev)
>  		return -EIO;
>  	}
>  
> -	status = pci_restore_state(pdev);
> -	if (status)
> -		return status;
> +	pci_restore_state(pdev);
>  
>  	status = pci_enable_device(pdev);
>  	if (status) {
> diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
> index 267019b..1763b9a 100644
> --- a/drivers/net/sfc/falcon.c
> +++ b/drivers/net/sfc/falcon.c
> @@ -1066,22 +1066,9 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
>  
>  	/* Restore PCI configuration if needed */
>  	if (method == RESET_TYPE_WORLD) {
> -		if (efx_nic_is_dual_func(efx)) {
> -			rc = pci_restore_state(nic_data->pci_dev2);
> -			if (rc) {
> -				netif_err(efx, drv, efx->net_dev,
> -					  "failed to restore PCI config for "
> -					  "the secondary function\n");
> -				goto fail3;
> -			}
> -		}
> -		rc = pci_restore_state(efx->pci_dev);
> -		if (rc) {
> -			netif_err(efx, drv, efx->net_dev,
> -				  "failed to restore PCI config for the "
> -				  "primary function\n");
> -			goto fail4;
> -		}
> +		if (efx_nic_is_dual_func(efx))
> +			pci_restore_state(nic_data->pci_dev2);
> +		pci_restore_state(efx->pci_dev);
>  		netif_dbg(efx, drv, efx->net_dev,
>  			  "successfully restored PCI config\n");
>  	}
> @@ -1092,7 +1079,7 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
>  		rc = -ETIMEDOUT;
>  		netif_err(efx, hw, efx->net_dev,
>  			  "timed out waiting for hardware reset\n");
> -		goto fail5;
> +		goto fail3;
>  	}
>  	netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n");
>  
> @@ -1100,11 +1087,9 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
>  
>  	/* pci_save_state() and pci_restore_state() MUST be called in pairs */
>  fail2:
> -fail3:
>  	pci_restore_state(efx->pci_dev);
>  fail1:
> -fail4:
> -fail5:
> +fail3:
>  	return rc;
>  }
>  
> diff --git a/drivers/net/skge.c b/drivers/net/skge.c
> index 220e039..61553af 100644
> --- a/drivers/net/skge.c
> +++ b/drivers/net/skge.c
> @@ -4087,9 +4087,7 @@ static int skge_resume(struct pci_dev *pdev)
>  	if (err)
>  		goto out;
>  
> -	err = pci_restore_state(pdev);
> -	if (err)
> -		goto out;
> +	pci_restore_state(pdev);
>  
>  	err = skge_reset(hw);
>  	if (err)
> diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
> index d657708..be3aee7 100644
> --- a/drivers/net/sky2.c
> +++ b/drivers/net/sky2.c
> @@ -4969,10 +4969,7 @@ static int sky2_resume(struct pci_dev *pdev)
>  	if (err)
>  		goto out;
>  
> -	err = pci_restore_state(pdev);
> -	if (err)
> -		goto out;
> -
> +	pci_restore_state(pdev);
>  	pci_enable_wake(pdev, PCI_D0, 0);
>  
>  	/* Re-enable all clocks */
> diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
> index 868ca19..5e3c46f 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
> @@ -356,12 +356,12 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
>  	struct rt2x00_dev *rt2x00dev = hw->priv;
>  
>  	if (pci_set_power_state(pci_dev, PCI_D0) ||
> -	    pci_enable_device(pci_dev) ||
> -	    pci_restore_state(pci_dev)) {
> +	    pci_enable_device(pci_dev)) {
>  		ERROR(rt2x00dev, "Failed to resume device.\n");
>  		return -EIO;
>  	}
>  
> +	pci_restore_state(pci_dev);
>  	return rt2x00lib_resume(rt2x00dev);
>  }
>  EXPORT_SYMBOL_GPL(rt2x00pci_resume);
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index 8a6f797..80e551e 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -449,7 +449,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
>  			return error;
>  	}
>  
> -	return pci_restore_state(pci_dev);
> +	pci_restore_state(pci_dev);
> +	return 0;
>  }
>  
>  static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index e98c810..c711d1b 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -937,14 +937,13 @@ pci_save_state(struct pci_dev *dev)
>   * pci_restore_state - Restore the saved state of a PCI device
>   * @dev: - PCI device that we're dealing with
>   */
> -int 
> -pci_restore_state(struct pci_dev *dev)
> +void pci_restore_state(struct pci_dev *dev)
>  {
>  	int i;
>  	u32 val;
>  
>  	if (!dev->state_saved)
> -		return 0;
> +		return;
>  
>  	/* PCI Express register must be restored first */
>  	pci_restore_pcie_state(dev);
> @@ -968,8 +967,6 @@ pci_restore_state(struct pci_dev *dev)
>  	pci_restore_iov_state(dev);
>  
>  	dev->state_saved = false;
> -
> -	return 0;
>  }
>  
>  static int do_pci_enable_device(struct pci_dev *dev, int bars)
> diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
> index fa60d7d..1d7dbe6 100644
> --- a/drivers/scsi/ipr.c
> +++ b/drivers/scsi/ipr.c
> @@ -7485,16 +7485,10 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
>  {
>  	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
>  	volatile u32 int_reg;
> -	int rc;
>  
>  	ENTER;
>  	ioa_cfg->pdev->state_saved = true;
> -	rc = pci_restore_state(ioa_cfg->pdev);
> -
> -	if (rc != PCIBIOS_SUCCESSFUL) {
> -		ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
> -		return IPR_RC_JOB_CONTINUE;
> -	}
> +	pci_restore_state(ioa_cfg->pdev);
>  
>  	if (ipr_set_pcix_cmd_reg(ioa_cfg)) {
>  		ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
> diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
> index cf89091..091baf2 100644
> --- a/drivers/scsi/pmcraid.c
> +++ b/drivers/scsi/pmcraid.c
> @@ -2227,12 +2227,7 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
>  		/* Once either bist or pci reset is done, restore PCI config
>  		 * space. If this fails, proceed with hard reset again
>  		 */
> -		if (pci_restore_state(pinstance->pdev)) {
> -			pmcraid_info("config-space error resetting again\n");
> -			pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
> -			pmcraid_reset_alert(cmd);
> -			break;
> -		}
> +		pci_restore_state(pinstance->pdev);
>  
>  		/* fail all pending commands */
>  		pmcraid_fail_outstanding_cmds(pinstance);
> diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
> index 24f47d6..7162dee 100644
> --- a/drivers/staging/sm7xx/smtcfb.c
> +++ b/drivers/staging/sm7xx/smtcfb.c
> @@ -1071,7 +1071,7 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev)
>  	/* when resuming, restore pci data and fb cursor */
>  	if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) {
>  		retv = pci_set_power_state(pdev, PCI_D0);
> -		retv = pci_restore_state(pdev);
> +		pci_restore_state(pdev);
>  		if (pci_enable_device(pdev))
>  			return -1;
>  		pci_set_master(pdev);
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 7454408..63cbadc 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -806,7 +806,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size);
>  
>  /* Power management related routines */
>  int pci_save_state(struct pci_dev *dev);
> -int pci_restore_state(struct pci_dev *dev);
> +void pci_restore_state(struct pci_dev *dev);
>  int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state);
>  int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
>  pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
> @@ -1168,10 +1168,8 @@ static inline int pci_save_state(struct pci_dev *dev)
>  	return 0;
>  }
>  
> -static inline int pci_restore_state(struct pci_dev *dev)
> -{
> -	return 0;
> -}
> +static inline void pci_restore_state(struct pci_dev *dev)
> +{ }
>  
>  static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
>  {
> diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
> index a3301cc..185b000 100644
> --- a/sound/pci/cs5535audio/cs5535audio_pm.c
> +++ b/sound/pci/cs5535audio/cs5535audio_pm.c
> @@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
>  	int i;
>  
>  	pci_set_power_state(pci, PCI_D0);
> -	if (pci_restore_state(pci) < 0) {
> -		printk(KERN_ERR "cs5535audio: pci_restore_state failed, "
> -		       "disabling device\n");
> -		snd_card_disconnect(card);
> -		return -EIO;
> -	}
> +	pci_restore_state(pci);
>  	if (pci_enable_device(pci) < 0) {
>  		printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
>  		       "disabling device\n");


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox