Netdev List
 help / color / mirror / Atom feed
* [patch 3/7] netxen: improve MSI interrupt handling
From: dhananjay @ 2007-12-26 18:23 UTC (permalink / raw)
  To: netdev; +Cc: jeff
In-Reply-To: <20071226182352.704678179@netxen.com>

[-- Attachment #1: msifix.patch --]
[-- Type: text/plain, Size: 7306 bytes --]

Recent netxen firmware has new scheme of generating MSI interrupts, it
raises interrupt and blocks itself, waiting for driver to unmask. This
reduces chance of spurious interrupts.

The driver will be able to deal with older firmware as well.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>

Index: upstream/drivers/net/netxen/netxen_nic_hw.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_hw.c
+++ upstream/drivers/net/netxen/netxen_nic_hw.c
@@ -398,6 +398,8 @@ int netxen_nic_hw_resources(struct netxe
 		NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
 	printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name,
 			adapter->intr_scheme);
+	adapter->msi_mode = readl(
+		NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW));
 	DPRINTK(INFO, "Receive Peg ready too. starting stuff\n");
 
 	addr = netxen_alloc(adapter->ahw.pdev,
Index: upstream/drivers/net/netxen/netxen_nic_main.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_main.c
+++ upstream/drivers/net/netxen/netxen_nic_main.c
@@ -149,33 +149,33 @@ static void netxen_nic_update_cmd_consum
 
 #define	ADAPTER_LIST_SIZE 12
 
+static uint32_t msi_tgt_status[4] = {
+	ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
+	ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3
+};
+
+static uint32_t sw_int_mask[4] = {
+	CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
+	CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
+};
+
 static void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
-	uint32_t	mask = 0x7ff;
+	u32 mask;
 	int retries = 32;
+	int port = adapter->portnum;
+	int pci_fn = adapter->ahw.pci_func;
 
 	DPRINTK(1, INFO, "Entered ISR Disable \n");
 
-	switch (adapter->portnum) {
-	case 0:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-		break;
-	case 1:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-		break;
-	case 2:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-		break;
-	case 3:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-		break;
+	if (adapter->msi_mode != MSI_MODE_MULTIFUNC) {
+		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));
 	}
 
 	if (adapter->intr_scheme != -1 &&
 	    adapter->intr_scheme != INTR_SCHEME_PERPORT)
-		writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+		writel(0x7ff,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
 
-	/* Window = 0 or 1 */
 	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
 		do {
 			writel(0xffffffff,
@@ -190,6 +190,11 @@ static void netxen_nic_disable_int(struc
 			printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
 					netxen_nic_driver_name);
 		}
+	} else {
+		if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
+			writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter,
+						msi_tgt_status[pci_fn]));
+		}
 	}
 
 	DPRINTK(1, INFO, "Done with Disable Int\n");
@@ -198,6 +203,7 @@ static void netxen_nic_disable_int(struc
 static void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
 	u32 mask;
+	int port = adapter->portnum;
 
 	DPRINTK(1, INFO, "Entered ISR Enable \n");
 
@@ -218,20 +224,7 @@ static void netxen_nic_enable_int(struct
 		writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
 	}
 
-	switch (adapter->portnum) {
-	case 0:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-		break;
-	case 1:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-		break;
-	case 2:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-		break;
-	case 3:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-		break;
-	}
+	writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));
 
 	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
 		mask = 0xbff;
@@ -401,6 +394,7 @@ netxen_nic_probe(struct pci_dev *pdev, c
 
 	/* this will be read from FW later */
 	adapter->intr_scheme = -1;
+	adapter->msi_mode = -1;
 
 	/* This will be reset for mezz cards  */
 	adapter->portnum = pci_func_id;
Index: upstream/drivers/net/netxen/netxen_nic.h
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic.h
+++ upstream/drivers/net/netxen/netxen_nic.h
@@ -939,6 +939,7 @@ struct netxen_adapter {
 	struct pci_dev *ctx_desc_pdev;
 	dma_addr_t ctx_desc_phys_addr;
 	int intr_scheme;
+	int msi_mode;
 	int (*enable_phy_interrupts) (struct netxen_adapter *);
 	int (*disable_phy_interrupts) (struct netxen_adapter *);
 	void (*handle_phy_intr) (struct netxen_adapter *);
Index: upstream/drivers/net/netxen/netxen_nic_phan_reg.h
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_phan_reg.h
+++ upstream/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -126,8 +126,11 @@
  */
 #define CRB_NIC_CAPABILITIES_HOST	NETXEN_NIC_REG(0x1a8)
 #define CRB_NIC_CAPABILITIES_FW	  	NETXEN_NIC_REG(0x1dc)
+#define CRB_NIC_MSI_MODE_HOST		NETXEN_NIC_REG(0x270)
+#define CRB_NIC_MSI_MODE_FW	  		NETXEN_NIC_REG(0x274)
 
 #define INTR_SCHEME_PERPORT	      	0x1
+#define MSI_MODE_MULTIFUNC	      	0x1
 
 /* used for ethtool tests */
 #define CRB_SCRATCHPAD_TEST	    NETXEN_NIC_REG(0x280)
Index: upstream/drivers/net/netxen/netxen_nic_hdr.h
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_hdr.h
+++ upstream/drivers/net/netxen/netxen_nic_hdr.h
@@ -456,6 +456,12 @@ enum {
 #define ISR_INT_MASK_SLOW	(NETXEN_PCIX_PS_REG(PCIX_INT_MASK))
 #define ISR_INT_TARGET_STATUS	(NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS))
 #define ISR_INT_TARGET_MASK	(NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK))
+#define ISR_INT_TARGET_STATUS_F1   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F1))
+#define ISR_INT_TARGET_MASK_F1     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F1))
+#define ISR_INT_TARGET_STATUS_F2   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F2))
+#define ISR_INT_TARGET_MASK_F2     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2))
+#define ISR_INT_TARGET_STATUS_F3   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3))
+#define ISR_INT_TARGET_MASK_F3     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3))
 
 #define NETXEN_PCI_MAPSIZE	128
 #define NETXEN_PCI_DDR_NET	(0x00000000UL)
@@ -662,6 +668,12 @@ enum {
 
 #define PCIX_TARGET_STATUS	(0x10118)
 #define PCIX_TARGET_MASK	(0x10128)
+#define PCIX_TARGET_STATUS_F1 (0x10160)
+#define PCIX_TARGET_MASK_F1   (0x10170)
+#define PCIX_TARGET_STATUS_F2 (0x10164)
+#define PCIX_TARGET_MASK_F2   (0x10174)
+#define PCIX_TARGET_STATUS_F3 (0x10168)
+#define PCIX_TARGET_MASK_F3   (0x10178)
 
 #define PCIX_MSI_F0		(0x13000)
 #define PCIX_MSI_F1		(0x13004)
Index: upstream/drivers/net/netxen/netxen_nic_init.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_init.c
+++ upstream/drivers/net/netxen/netxen_nic_init.c
@@ -145,6 +145,8 @@ int netxen_init_firmware(struct netxen_a
 	/* Window 1 call */
 	writel(INTR_SCHEME_PERPORT,
 	       NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST));
+	writel(MSI_MODE_MULTIFUNC,
+	       NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_HOST));
 	writel(MPORT_MULTI_FUNCTION_MODE,
 	       NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
 	writel(PHAN_INITIALIZE_ACK,

-- 

^ permalink raw reply

* [patch 5/7] netxen: fix race in interrupt / napi
From: dhananjay @ 2007-12-26 18:23 UTC (permalink / raw)
  To: netdev; +Cc: jeff
In-Reply-To: <20071226182352.704678179@netxen.com>

[-- Attachment #1: poll.patch --]
[-- Type: text/plain, Size: 8709 bytes --]

This patch simplifies netxen ISR and poll() routine. Interrupts are not
unmasked in interrupt routine based on a racy has_work() checks, but
left to the napi poll function to enable them. 

This also fixes crash in netif_rx_action(), when work_done == budget.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>

Index: upstream/drivers/net/netxen/netxen_nic_main.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_main.c
+++ upstream/drivers/net/netxen/netxen_nic_main.c
@@ -63,7 +63,6 @@ static int netxen_nic_xmit_frame(struct 
 static void netxen_tx_timeout(struct net_device *netdev);
 static void netxen_tx_timeout_task(struct work_struct *work);
 static void netxen_watchdog(unsigned long);
-static int netxen_handle_int(struct netxen_adapter *, struct net_device *);
 static int netxen_nic_poll(struct napi_struct *napi, int budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void netxen_nic_poll_controller(struct net_device *netdev);
@@ -1218,40 +1217,6 @@ static void netxen_tx_timeout_task(struc
 	netif_wake_queue(adapter->netdev);
 }
 
-static int
-netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
-{
-	u32 ret = 0;
-
-	DPRINTK(INFO, "Entered handle ISR\n");
-	adapter->stats.ints++;
-
-	netxen_nic_disable_int(adapter);
-
-	if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
-		if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
-			/*
-			 * Interrupts are already disabled.
-			 */
-			__netif_rx_schedule(netdev, &adapter->napi);
-		} else {
-			static unsigned int intcount = 0;
-			if ((++intcount & 0xfff) == 0xfff)
-				DPRINTK(KERN_ERR
-				       "%s: %s interrupt %d while in poll\n",
-				       netxen_nic_driver_name, netdev->name,
-				       intcount);
-		}
-		ret = 1;
-	}
-
-	if (ret == 0) {
-		netxen_nic_enable_int(adapter);
-	}
-
-	return ret;
-}
-
 /*
  * netxen_intr - Interrupt Handler
  * @irq: interrupt number
@@ -1278,8 +1243,12 @@ irqreturn_t netxen_intr(int irq, void *d
 		}
 	}
 
-	if (netif_running(netdev))
-		netxen_handle_int(adapter, netdev);
+	adapter->stats.ints++;
+
+	if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
+		netxen_nic_disable_int(adapter);
+		__netif_rx_schedule(netdev, &adapter->napi);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -1287,12 +1256,11 @@ irqreturn_t netxen_intr(int irq, void *d
 static int netxen_nic_poll(struct napi_struct *napi, int budget)
 {
 	struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi);
-	struct net_device *netdev = adapter->netdev;
-	int done = 1;
+	int tx_complete;
 	int ctx;
 	int work_done;
 
-	DPRINTK(INFO, "polling for %d descriptors\n", *budget);
+	tx_complete = netxen_process_cmd_ring(adapter);
 
 	work_done = 0;
 	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
@@ -1312,16 +1280,8 @@ static int netxen_nic_poll(struct napi_s
 						     budget / MAX_RCV_CTX);
 	}
 
-	if (work_done >= budget && netxen_nic_rx_has_work(adapter) != 0)
-		done = 0;
-
-	if (netxen_process_cmd_ring((unsigned long)adapter) == 0)
-		done = 0;
-
-	DPRINTK(INFO, "new work_done: %d work_to_do: %d\n",
-		work_done, work_to_do);
-	if (done) {
-		netif_rx_complete(netdev, napi);
+	if ((work_done < budget) && tx_complete) {
+		netif_rx_complete(adapter->netdev, &adapter->napi);
 		netxen_nic_enable_int(adapter);
 	}
 
Index: upstream/drivers/net/netxen/netxen_nic.h
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic.h
+++ upstream/drivers/net/netxen/netxen_nic.h
@@ -839,7 +839,6 @@ struct netxen_rcv_desc_ctx {
 	u32 flags;
 	u32 producer;
 	u32 rcv_pending;	/* Num of bufs posted in phantom */
-	u32 rcv_free;		/* Num of bufs in free list */
 	dma_addr_t phys_addr;
 	struct pci_dev *phys_pdev;
 	struct rcv_desc *desc_head;	/* address of rx ring in Phantom */
@@ -1073,12 +1072,10 @@ void netxen_tso_check(struct netxen_adap
 		      struct cmd_desc_type0 *desc, struct sk_buff *skb);
 int netxen_nic_hw_resources(struct netxen_adapter *adapter);
 void netxen_nic_clear_stats(struct netxen_adapter *adapter);
-int netxen_nic_rx_has_work(struct netxen_adapter *adapter);
-int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
 			    u32 ringid);
-int netxen_process_cmd_ring(unsigned long data);
+int netxen_process_cmd_ring(struct netxen_adapter *adapter);
 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
 void netxen_nic_set_multi(struct net_device *netdev);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
Index: upstream/drivers/net/netxen/netxen_nic_init.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_init.c
+++ upstream/drivers/net/netxen/netxen_nic_init.c
@@ -185,7 +185,6 @@ void netxen_initialize_adapter_sw(struct
 		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
 			struct netxen_rx_buffer *rx_buf;
 			rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring];
-			rcv_desc->rcv_free = rcv_desc->max_rx_desc_count;
 			rcv_desc->begin_alloc = 0;
 			rx_buf = rcv_desc->rx_buf_arr;
 			num_rx_bufs = rcv_desc->max_rx_desc_count;
@@ -975,28 +974,6 @@ int netxen_phantom_init(struct netxen_ad
 	return 0;
 }
 
-int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
-{
-	int ctx;
-
-	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-		struct netxen_recv_context *recv_ctx =
-		    &(adapter->recv_ctx[ctx]);
-		u32 consumer;
-		struct status_desc *desc_head;
-		struct status_desc *desc;
-
-		consumer = recv_ctx->status_rx_consumer;
-		desc_head = recv_ctx->rcv_status_desc_head;
-		desc = &desc_head[consumer];
-
-		if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)
-			return 1;
-	}
-
-	return 0;
-}
-
 static int netxen_nic_check_temp(struct netxen_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
@@ -1175,7 +1152,6 @@ static void netxen_process_rcv(struct ne
 
 	netdev->last_rx = jiffies;
 
-	rcv_desc->rcv_free++;
 	rcv_desc->rcv_pending--;
 
 	/*
@@ -1231,23 +1207,22 @@ u32 netxen_process_rcv_ring(struct netxe
 		recv_ctx->status_rx_consumer = consumer;
 		recv_ctx->status_rx_producer = producer;
 
+		smp_wmb();
 		/* Window = 1 */
 		writel(consumer,
 		       NETXEN_CRB_NORMALIZE(adapter,
 					    recv_crb_registers[adapter->portnum].
 					    crb_rcv_status_consumer));
-		wmb();
 	}
 
 	return count;
 }
 
 /* Process Command status ring */
-int netxen_process_cmd_ring(unsigned long data)
+int netxen_process_cmd_ring(struct netxen_adapter *adapter)
 {
 	u32 last_consumer;
 	u32 consumer;
-	struct netxen_adapter *adapter = (struct netxen_adapter *)data;
 	int count1 = 0;
 	int count2 = 0;
 	struct netxen_cmd_buffer *buffer;
@@ -1353,11 +1328,7 @@ int netxen_process_cmd_ring(unsigned lon
 	 * There is still a possible race condition and the host could miss an
 	 * interrupt. The card has to take care of this.
 	 */
-	if (adapter->last_cmd_consumer == consumer &&
-	    (((adapter->cmd_producer + 1) %
-	      adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) {
-		consumer = le32_to_cpu(*(adapter->cmd_consumer));
-	}
+	consumer = le32_to_cpu(*(adapter->cmd_consumer));
 	done = (adapter->last_cmd_consumer == consumer);
 
 	spin_unlock(&adapter->tx_lock);
@@ -1436,8 +1407,6 @@ void netxen_post_rx_buffers(struct netxe
 		rcv_desc->begin_alloc = index;
 		rcv_desc->rcv_pending += count;
 		rcv_desc->producer = producer;
-		if (rcv_desc->rcv_free >= 32) {
-			rcv_desc->rcv_free = 0;
 			/* Window = 1 */
 			writel((producer - 1) &
 			       (rcv_desc->max_rx_desc_count - 1),
@@ -1461,8 +1430,6 @@ void netxen_post_rx_buffers(struct netxe
 			writel(msg,
 			       DB_NORMALIZE(adapter,
 					    NETXEN_RCV_PRODUCER_OFFSET));
-			wmb();
-		}
 	}
 }
 
@@ -1526,8 +1493,6 @@ static void netxen_post_rx_buffers_nodb(
 		rcv_desc->begin_alloc = index;
 		rcv_desc->rcv_pending += count;
 		rcv_desc->producer = producer;
-		if (rcv_desc->rcv_free >= 32) {
-			rcv_desc->rcv_free = 0;
 			/* Window = 1 */
 			writel((producer - 1) &
 			       (rcv_desc->max_rx_desc_count - 1),
@@ -1537,21 +1502,9 @@ static void netxen_post_rx_buffers_nodb(
 						    rcv_desc_crb[ringid].
 						    crb_rcv_producer_offset));
 			wmb();
-		}
 	}
 }
 
-int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
-{
-	if (find_diff_among(adapter->last_cmd_consumer,
-			    adapter->cmd_producer,
-			    adapter->max_tx_desc_count) > 0)
-		return 1;
-
-	return 0;
-}
-
-
 void netxen_nic_clear_stats(struct netxen_adapter *adapter)
 {
 	memset(&adapter->stats, 0, sizeof(adapter->stats));

-- 

^ permalink raw reply

* [patch 6/7] netxen: optimize tx handling
From: dhananjay @ 2007-12-26 18:23 UTC (permalink / raw)
  To: netdev; +Cc: jeff
In-Reply-To: <20071226182352.704678179@netxen.com>

[-- Attachment #1: xmit.patch --]
[-- Type: text/plain, Size: 4928 bytes --]

netxen driver allows limited number of threads simultaneously posting
skb's in tx ring. If transmit slot is unavailable, driver calls
schedule() or loops in xmit_frame().

This patch returns TX_BUSY and lets the stack reschedule the packet if
transmit slot is unavailable. Also removes unnecessary check for tx
timeout in the driver itself, the network stack does that anyway.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>

Index: upstream/drivers/net/netxen/netxen_nic_main.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_main.c
+++ upstream/drivers/net/netxen/netxen_nic_main.c
@@ -986,28 +986,6 @@ static int netxen_nic_xmit_frame(struct 
 		return NETDEV_TX_OK;
 	}
 
-	/*
-	 * Everything is set up. Now, we just need to transmit it out.
-	 * Note that we have to copy the contents of buffer over to
-	 * right place. Later on, this can be optimized out by de-coupling the
-	 * producer index from the buffer index.
-	 */
-      retry_getting_window:
-	spin_lock_bh(&adapter->tx_lock);
-	if (adapter->total_threads >= MAX_XMIT_PRODUCERS) {
-		spin_unlock_bh(&adapter->tx_lock);
-		/*
-		 * Yield CPU
-		 */
-		if (!in_atomic())
-			schedule();
-		else {
-			for (i = 0; i < 20; i++)
-				cpu_relax();	/*This a nop instr on i386 */
-		}
-		goto retry_getting_window;
-	}
-	local_producer = adapter->cmd_producer;
 	/* There 4 fragments per descriptor */
 	no_of_desc = (frag_count + 3) >> 2;
 	if (netdev->features & NETIF_F_TSO) {
@@ -1021,16 +999,19 @@ static int netxen_nic_xmit_frame(struct 
 			}
 		}
 	}
+
+	spin_lock_bh(&adapter->tx_lock);
+	if (adapter->total_threads >= MAX_XMIT_PRODUCERS) {
+		goto out_requeue;
+	}
+	local_producer = adapter->cmd_producer;
 	k = adapter->cmd_producer;
 	max_tx_desc_count = adapter->max_tx_desc_count;
 	last_cmd_consumer = adapter->last_cmd_consumer;
 	if ((k + no_of_desc) >=
 	    ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
 	     last_cmd_consumer)) {
-		netif_stop_queue(netdev);
-		adapter->flags |= NETXEN_NETDEV_STATUS;
-		spin_unlock_bh(&adapter->tx_lock);
-		return NETDEV_TX_BUSY;
+		goto out_requeue;
 	}
 	k = get_index_range(k, max_tx_desc_count, no_of_desc);
 	adapter->cmd_producer = k;
@@ -1083,6 +1064,8 @@ static int netxen_nic_xmit_frame(struct 
 						  adapter->max_tx_desc_count);
 			hwdesc = &hw->cmd_desc_head[producer];
 			memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+			pbuf = &adapter->cmd_buf_arr[producer];
+			pbuf->skb = NULL;
 		}
 		frag = &skb_shinfo(skb)->frags[i - 1];
 		len = frag->size;
@@ -1138,6 +1121,8 @@ static int netxen_nic_xmit_frame(struct 
 		}
 		/* copy the MAC/IP/TCP headers to the cmd descriptor list */
 		hwdesc = &hw->cmd_desc_head[producer];
+		pbuf = &adapter->cmd_buf_arr[producer];
+		pbuf->skb = NULL;
 
 		/* copy the first 64 bytes */
 		memcpy(((void *)hwdesc) + 2,
@@ -1146,6 +1131,8 @@ static int netxen_nic_xmit_frame(struct 
 
 		if (more_hdr) {
 			hwdesc = &hw->cmd_desc_head[producer];
+			pbuf = &adapter->cmd_buf_arr[producer];
+			pbuf->skb = NULL;
 			/* copy the next 64 bytes - should be enough except
 			 * for pathological case
 			 */
@@ -1179,14 +1166,17 @@ static int netxen_nic_xmit_frame(struct 
 	}
 
 	adapter->stats.xmitfinished++;
-	spin_unlock_bh(&adapter->tx_lock);
-
 	netdev->trans_start = jiffies;
 
-	DPRINTK(INFO, "wrote CMD producer %x to phantom\n", producer);
-
-	DPRINTK(INFO, "Done. Send\n");
+	spin_unlock_bh(&adapter->tx_lock);
 	return NETDEV_TX_OK;
+
+out_requeue:
+	netif_stop_queue(netdev);
+	adapter->flags |= NETXEN_NETDEV_STATUS;
+
+	spin_unlock_bh(&adapter->tx_lock);
+	return NETDEV_TX_BUSY;
 }
 
 static void netxen_watchdog(unsigned long v)
Index: upstream/drivers/net/netxen/netxen_nic_init.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_init.c
+++ upstream/drivers/net/netxen/netxen_nic_init.c
@@ -1229,7 +1229,6 @@ int netxen_process_cmd_ring(struct netxe
 	struct pci_dev *pdev;
 	struct netxen_skb_frag *frag;
 	u32 i;
-	struct sk_buff *skb = NULL;
 	int done;
 
 	spin_lock(&adapter->tx_lock);
@@ -1259,9 +1258,8 @@ int netxen_process_cmd_ring(struct netxe
 	while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) {
 		buffer = &adapter->cmd_buf_arr[last_consumer];
 		pdev = adapter->pdev;
-		frag = &buffer->frag_array[0];
-		skb = buffer->skb;
-		if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) {
+		if (buffer->skb) {
+			frag = &buffer->frag_array[0];
 			pci_unmap_single(pdev, frag->dma, frag->length,
 					 PCI_DMA_TODEVICE);
 			frag->dma = 0ULL;
@@ -1274,8 +1272,8 @@ int netxen_process_cmd_ring(struct netxe
 			}
 
 			adapter->stats.skbfreed++;
-			dev_kfree_skb_any(skb);
-			skb = NULL;
+			dev_kfree_skb_any(buffer->skb);
+			buffer->skb = NULL;
 		} else if (adapter->proc_cmd_buf_counter == 1) {
 			adapter->stats.txnullskb++;
 		}

-- 

^ permalink raw reply

* [patch 4/7] netxen: stop second phy correctly
From: dhananjay @ 2007-12-26 18:23 UTC (permalink / raw)
  To: netdev; +Cc: jeff
In-Reply-To: <20071226182352.704678179@netxen.com>

[-- Attachment #1: stop_port.patch --]
[-- Type: text/plain, Size: 1691 bytes --]

This patch fixes bug that doesn't quiesce second port when interface is
brought down, which could lead to unwarranted interrupt during rmmod / 
ifdown.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>

Index: upstream/drivers/net/netxen/netxen_nic_niu.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_niu.c
+++ upstream/drivers/net/netxen/netxen_nic_niu.c
@@ -742,12 +742,12 @@ int netxen_niu_disable_xg_port(struct ne
 	__u32 mac_cfg;
 	u32 port = physical_port[adapter->portnum];
 
-	if (port != 0)
+	if (port > NETXEN_NIU_MAX_XG_PORTS)
 		return -EINVAL;
+
 	mac_cfg = 0;
-	netxen_xg_soft_reset(mac_cfg);
-	if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0,
-				   &mac_cfg, 4))
+	if (netxen_nic_hw_write_wx(adapter,
+		NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
 		return -EIO;
 	return 0;
 }
Index: upstream/drivers/net/netxen/netxen_nic_main.c
===================================================================
--- upstream.orig/drivers/net/netxen/netxen_nic_main.c
+++ upstream/drivers/net/netxen/netxen_nic_main.c
@@ -725,11 +725,6 @@ static void __devexit netxen_nic_remove(
 
 	unregister_netdev(netdev);
 
-	if (adapter->stop_port)
-		adapter->stop_port(adapter);
-
-	netxen_nic_disable_int(adapter);
-
 	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
 		init_firmware_done++;
 		netxen_free_hw_resources(adapter);
@@ -912,6 +907,9 @@ static int netxen_nic_close(struct net_d
 	netif_stop_queue(netdev);
 	napi_disable(&adapter->napi);
 
+	if (adapter->stop_port)
+		adapter->stop_port(adapter);
+
 	netxen_nic_disable_int(adapter);
 
 	cmd_buff = adapter->cmd_buf_arr;

-- 

^ permalink raw reply

* [patch 7/7] netxen: fix byte-swapping in tx and rx
From: dhananjay @ 2007-12-26 18:23 UTC (permalink / raw)
  To: netdev; +Cc: jeff
In-Reply-To: <20071226182352.704678179@netxen.com>

[-- Attachment #1: endian.patch --]
[-- Type: text/plain, Size: 6461 bytes --]

This cleans up some unnecessary byte-swapping while setting up tx and
interpreting rx desc. The 64 bit rx status data should be converted
to host endian format only once and the macros just need to extract
bitfields.

This saves a spate of interrupts on pseries blades caused by buggy 
(non) processing rx status ring.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>

Index: netdev-2.6/drivers/net/netxen/netxen_nic.h
===================================================================
--- netdev-2.6.orig/drivers/net/netxen/netxen_nic.h
+++ netdev-2.6/drivers/net/netxen/netxen_nic.h
@@ -309,23 +309,23 @@ struct netxen_ring_ctx {
 	((cmd_desc)->port_ctxid |= ((var) & 0xF0))
 
 #define netxen_set_cmd_desc_flags(cmd_desc, val)	\
-	((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \
-	(cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f))
+	((cmd_desc)->flags_opcode &= ~(0x7f), \
+	(cmd_desc)->flags_opcode |= (val) & 0x7f)
 #define netxen_set_cmd_desc_opcode(cmd_desc, val)	\
-	((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \
-	(cmd_desc)->flags_opcode |= cpu_to_le16(((val & 0x3f)<<7)))
+	((cmd_desc)->flags_opcode &= ~(0x3f<<7), \
+	(cmd_desc)->flags_opcode |= ((val) & 0x3f) << 7)
 
 #define netxen_set_cmd_desc_num_of_buff(cmd_desc, val)	\
-	((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xff), \
-	(cmd_desc)->num_of_buffers_total_length |= cpu_to_le32((val) & 0xff))
+	((cmd_desc)->num_of_buffers_total_length &= ~(0xff), \
+	(cmd_desc)->num_of_buffers_total_length |= (val) & 0xff)
 #define netxen_set_cmd_desc_totallength(cmd_desc, val)	\
-	((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xffffff00), \
-	(cmd_desc)->num_of_buffers_total_length |= cpu_to_le32(val << 8))
+	((cmd_desc)->num_of_buffers_total_length &= ~(0xffffff << 8), \
+	(cmd_desc)->num_of_buffers_total_length |= (val) << 8)
 
 #define netxen_get_cmd_desc_opcode(cmd_desc)	\
-	((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003F)
+	(((cmd_desc)->flags_opcode >> 7) & 0x003f)
 #define netxen_get_cmd_desc_totallength(cmd_desc)	\
-	(le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8)
+	(((cmd_desc)->num_of_buffers_total_length >> 8) & 0xffffff)
 
 struct cmd_desc_type0 {
 	u8 tcp_hdr_offset;	/* For LSO only */
@@ -412,29 +412,29 @@ struct rcv_desc {
 #define netxen_get_sts_desc_lro_last_frag(status_desc)	\
 	(((status_desc)->lro & 0x80) >> 7)
 
-#define netxen_get_sts_port(status_desc)	\
-	(le64_to_cpu((status_desc)->status_desc_data) & 0x0F)
-#define netxen_get_sts_status(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 4) & 0x0F)
-#define netxen_get_sts_type(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 8) & 0x0F)
-#define netxen_get_sts_totallength(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 12) & 0xFFFF)
-#define netxen_get_sts_refhandle(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 28) & 0xFFFF)
-#define netxen_get_sts_prot(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 44) & 0x0F)
-#define netxen_get_sts_owner(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03)
-#define netxen_get_sts_opcode(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 58) & 0x03F)
-
-#define netxen_clear_sts_owner(status_desc)	\
-	((status_desc)->status_desc_data &=	\
-	~cpu_to_le64(((unsigned long long)3) << 56 ))
-#define netxen_set_sts_owner(status_desc, val)	\
-	((status_desc)->status_desc_data |=	\
-	cpu_to_le64(((unsigned long long)((val) & 0x3)) << 56 ))
+#define netxen_get_sts_port(sts_data)	\
+	((sts_data) & 0x0F)
+#define netxen_get_sts_status(sts_data)	\
+	(((sts_data) >> 4) & 0x0F)
+#define netxen_get_sts_type(sts_data)	\
+	(((sts_data) >> 8) & 0x0F)
+#define netxen_get_sts_totallength(sts_data)	\
+	(((sts_data) >> 12) & 0xFFFF)
+#define netxen_get_sts_refhandle(sts_data)	\
+	(((sts_data) >> 28) & 0xFFFF)
+#define netxen_get_sts_prot(sts_data)	\
+	(((sts_data) >> 44) & 0x0F)
+#define netxen_get_sts_owner(sts_data)	\
+	(((sts_data) >> 56) & 0x03)
+#define netxen_get_sts_opcode(sts_data)	\
+	(((sts_data) >> 58) & 0x03F)
+
+#define netxen_set_sts_owner(status_desc, val)	{ \
+	u64 value = le64_to_cpu((status_desc)->status_desc_data); \
+	value &= ~(0x3ULL << 56); \
+	value |= (u64)(((u64)(val) << 56) & (0x3ULL << 56)); \
+	(status_desc)->status_desc_data = cpu_to_le64(value); \
+}
 
 struct status_desc {
 	/* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
Index: netdev-2.6/drivers/net/netxen/netxen_nic_init.c
===================================================================
--- netdev-2.6.orig/drivers/net/netxen/netxen_nic_init.c
+++ netdev-2.6/drivers/net/netxen/netxen_nic_init.c
@@ -1053,16 +1053,17 @@ static void netxen_process_rcv(struct ne
 {
 	struct pci_dev *pdev = adapter->pdev;
 	struct net_device *netdev = adapter->netdev;
-	int index = netxen_get_sts_refhandle(desc);
+	u64 sts_data = le64_to_cpu(desc->status_desc_data);
+	int index = netxen_get_sts_refhandle(sts_data);
 	struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
 	struct netxen_rx_buffer *buffer;
 	struct sk_buff *skb;
-	u32 length = netxen_get_sts_totallength(desc);
+	u32 length = netxen_get_sts_totallength(sts_data);
 	u32 desc_ctx;
 	struct netxen_rcv_desc_ctx *rcv_desc;
 	int ret;
 
-	desc_ctx = netxen_get_sts_type(desc);
+	desc_ctx = netxen_get_sts_type(sts_data);
 	if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
 		printk("%s: %s Bad Rcv descriptor ring\n",
 		       netxen_nic_driver_name, netdev->name);
@@ -1102,7 +1103,7 @@ static void netxen_process_rcv(struct ne
 	skb = (struct sk_buff *)buffer->skb;
 
 	if (likely(adapter->rx_csum &&
-				netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) {
+				netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) {
 		adapter->stats.csummed++;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	} else
@@ -1185,13 +1186,12 @@ u32 netxen_process_rcv_ring(struct netxe
 	 */
 	while (count < max) {
 		desc = &desc_head[consumer];
-		if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
+		if (!(netxen_get_sts_owner(le64_to_cpu(desc->status_desc_data)) & STATUS_OWNER_HOST)) {
 			DPRINTK(ERR, "desc %p ownedby %x\n", desc,
 				netxen_get_sts_owner(desc));
 			break;
 		}
 		netxen_process_rcv(adapter, ctxid, desc);
-		netxen_clear_sts_owner(desc);
 		netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
 		consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
 		count++;

-- 

^ permalink raw reply

* Re: Strange Panic (Deadlock)
From: Jarek Poplawski @ 2007-12-26 18:54 UTC (permalink / raw)
  To: Badalian Vyacheslav; +Cc: netdev
In-Reply-To: <4770C956.5040409@bigtelecom.ru>

On Tue, Dec 25, 2007 at 12:11:50PM +0300, Badalian Vyacheslav wrote:
...
> I have 4 machine. All platforms different.   All machine do 1 time in
> hour rebuild TC and IPTABLES rules.
> After it do
> echo START >> log.txt
> iptables-restore < xxx.txt
> tc qdisc del dev eth0 root
> tc qdisc del dev eth1 root
> tc -b new_rules.txt
> echo END >> log.txt
> 
> and its all that its doing.
> Bug always be between START and END
> All machines have above 300mbs traffic.
> I try turn off rebuilding rules on 1 PC and it work 3 week without reboot!

Hi Slavon,

After some looking around net schedulers' timers I think you could try
these 3 patches (2 in next messages). They should change 3 suspicious
(maybe only to me) places, but it's only guessing, to eliminate some
most nearby possibilities. These patches are independent, but of course
trying all at once should be quicker.
 
Thanks,
Jarek P.

[PATCH 1/3]
---

diff -Nurp linux-2.6.23.12-/net/sched/sch_generic.c linux-2.6.23.12+/net/sched/sch_generic.c
--- linux-2.6.23.12-/net/sched/sch_generic.c	2007-12-21 22:26:15.000000000 +0100
+++ linux-2.6.23.12+/net/sched/sch_generic.c	2007-12-26 18:39:20.000000000 +0100
@@ -251,10 +251,8 @@ static void dev_watchdog_up(struct net_d
 
 static void dev_watchdog_down(struct net_device *dev)
 {
-	netif_tx_lock_bh(dev);
-	if (del_timer(&dev->watchdog_timer))
+	if (del_timer_sync(&dev->watchdog_timer))
 		dev_put(dev);
-	netif_tx_unlock_bh(dev);
 }
 
 void netif_carrier_on(struct net_device *dev)
@@ -560,6 +558,8 @@ void dev_deactivate(struct net_device *d
 	struct Qdisc *qdisc;
 	struct sk_buff *skb;
 
+	dev_watchdog_down(dev);
+
 	spin_lock_bh(&dev->queue_lock);
 	qdisc = dev->qdisc;
 	dev->qdisc = &noop_qdisc;
@@ -572,8 +572,6 @@ void dev_deactivate(struct net_device *d
 
 	kfree_skb(skb);
 
-	dev_watchdog_down(dev);
-
 	/* Wait for outstanding dev_queue_xmit calls. */
 	synchronize_rcu();
 

^ permalink raw reply

* Re: Strange Panic (Deadlock)
From: Jarek Poplawski @ 2007-12-26 18:56 UTC (permalink / raw)
  To: Badalian Vyacheslav; +Cc: netdev
In-Reply-To: <20071226185411.GA3061@ami.dom.local>

On Wed, Dec 26, 2007 at 07:54:11PM +0100, Jarek Poplawski wrote:
...

[PATCH 2/3] (for testing only)
---

diff -Nurp linux-2.6.23.12-/net/sched/sch_sfq.c linux-2.6.23.12+/net/sched/sch_sfq.c
--- linux-2.6.23.12-/net/sched/sch_sfq.c	2007-10-09 22:31:38.000000000 +0200
+++ linux-2.6.23.12+/net/sched/sch_sfq.c	2007-12-26 12:45:06.000000000 +0100
@@ -457,7 +457,7 @@ static int sfq_init(struct Qdisc *sch, s
 static void sfq_destroy(struct Qdisc *sch)
 {
 	struct sfq_sched_data *q = qdisc_priv(sch);
-	del_timer(&q->perturb_timer);
+	del_timer_sync(&q->perturb_timer);
 }
 
 static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)

^ permalink raw reply

* Re: Strange Panic (Deadlock)
From: Jarek Poplawski @ 2007-12-26 18:58 UTC (permalink / raw)
  To: Badalian Vyacheslav; +Cc: netdev
In-Reply-To: <20071226185642.GB3061@ami.dom.local>

On Wed, Dec 26, 2007 at 07:56:42PM +0100, Jarek Poplawski wrote:
...

[PATCH 3/3] (for testing only)
---

diff -Nurp linux-2.6.23.12-/net/sched/sch_api.c linux-2.6.23.12+/net/sched/sch_api.c
--- linux-2.6.23.12-/net/sched/sch_api.c	2007-12-21 22:26:15.000000000 +0100
+++ linux-2.6.23.12+/net/sched/sch_api.c	2007-12-26 13:35:46.000000000 +0100
@@ -514,8 +514,11 @@ qdisc_create(struct net_device *dev, u32
 				 * a ops->reset() here? The qdisc was never
 				 * in action so it shouldn't be necessary.
 				 */
-				if (ops->destroy)
+				if (ops->destroy) {
+					qdisc_lock_tree(dev);
 					ops->destroy(sch);
+					qdisc_unlock_tree(dev);
+				}
 				goto err_out3;
 			}
 		}

^ permalink raw reply

* Re: [patch 7/7] netxen: fix byte-swapping in tx and rx
From: Al Viro @ 2007-12-26 22:38 UTC (permalink / raw)
  To: dhananjay; +Cc: netdev, jeff
In-Reply-To: <20071226182928.425988922@netxen.com>

On Wed, Dec 26, 2007 at 10:23:59AM -0800, dhananjay@netxen.com wrote:
> This cleans up some unnecessary byte-swapping while setting up tx and
> interpreting rx desc. The 64 bit rx status data should be converted
> to host endian format only once and the macros just need to extract
> bitfields.
 
> -	(cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f))
> +	((cmd_desc)->flags_opcode &= ~(0x7f), \
> +	(cmd_desc)->flags_opcode |= (val) & 0x7f)
>  #define netxen_set_cmd_desc_opcode(cmd_desc, val)	\
> -	((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \
> -	(cmd_desc)->flags_opcode |= cpu_to_le16(((val & 0x3f)<<7)))
> +	((cmd_desc)->flags_opcode &= ~(0x3f<<7), \
> +	(cmd_desc)->flags_opcode |= ((val) & 0x3f) << 7)

_oh_?

That's actually a pessimisation and I'd rather see that conversion in
place gone - the thing will be less brittle that way.

BTW, note that cpu_to_le16() et.al. get evaluated by compiler when the
argument is constant.

^ permalink raw reply

* Re: [patch 7/7] netxen: fix byte-swapping in tx and rx
From: Dhananjay Phadke @ 2007-12-26 23:29 UTC (permalink / raw)
  To: Al Viro; +Cc: netdev, jeff
In-Reply-To: <20071226223803.GE27894@ZenIV.linux.org.uk>

I agree for tx desc, the compiler would optimize.

But for rx (status) desc, I didn't like multiple le64_to_cpu() 
for extracting various fields out of same status dword.

-Dhananjay

On Wed, 26 Dec 2007, Al Viro wrote:

> On Wed, Dec 26, 2007 at 10:23:59AM -0800, dhananjay@netxen.com wrote:
> > This cleans up some unnecessary byte-swapping while setting up tx and
> > interpreting rx desc. The 64 bit rx status data should be converted
> > to host endian format only once and the macros just need to extract
> > bitfields.
>  
> > -	(cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f))
> > +	((cmd_desc)->flags_opcode &= ~(0x7f), \
> > +	(cmd_desc)->flags_opcode |= (val) & 0x7f)
> >  #define netxen_set_cmd_desc_opcode(cmd_desc, val)	\
> > -	((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \
> > -	(cmd_desc)->flags_opcode |= cpu_to_le16(((val & 0x3f)<<7)))
> > +	((cmd_desc)->flags_opcode &= ~(0x3f<<7), \
> > +	(cmd_desc)->flags_opcode |= ((val) & 0x3f) << 7)
> 
> _oh_?
> 
> That's actually a pessimisation and I'd rather see that conversion in
> place gone - the thing will be less brittle that way.
> 
> BTW, note that cpu_to_le16() et.al. get evaluated by compiler when the
> argument is constant.
> 

^ permalink raw reply

* Re: [PATCH 0/4] Pull request for 'sis190' branch
From: Francois Romieu @ 2007-12-26 23:17 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Andrew Morton, netdev, K.M. Liu
In-Reply-To: <476703B9.7010604@garzik.org>

Jeff Garzik <jeff@garzik.org> :
[...]
>> Shortlog
>> --------
>>
>> Francois Romieu (4):
>>       sis190: add cmos ram access code for the SiS19x/968 chipset pair
>>       sis190: remove duplicate INIT_WORK
>>       sis190: mdio operation failure is not correctly detected
>>       sis190: scheduling while atomic error
>
> pulled into #upstream

Imho no owner of a 968 south bridge will be able to use his integrated
network device as long as "sis190: add cmos ram access code ..." is
not included upstream. Waiting for 2.6.25 means no hardware support
before march 2008.

-- 
Ueimor

^ permalink raw reply

* [PATCH 2.6.25 1/1]S2io: Multiqueue network device support implementation
From: Sreenivasa Honnur @ 2007-12-26 23:33 UTC (permalink / raw)
  To: netdev, jeff; +Cc: support

Multiqueue netwrok device support implementation.
- Added a loadable parameter "multiq" to enable/disable multiqueue support,
  by default it is disabled.
- skb->queue_mapping is not used for queue/fifo selection. FIFO iselection is
  based on IP-TOS value, 0x0-0xF TOS values are mapped to 8 FIFOs.
- Added per FIFO flags FIFO_QUEUE_START and FIFO_QUEUE_STOP. Check this flag
  for starting and stopping netif queue and update the flags accordingly.
- In tx_intr_handler added a check to ensure that we have free TXDs before wak-
  ing up the queue.
- Added helper functions for queue manipulation(start/stop/wakeup) to invoke
  appropriate netif_ functions.
- Calling netif_start/stop for link up/down case respectively.

Signed-off-by: Surjit Reang <surjit.reang@neterion.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
---
diff -Nurp orig/drivers/net/s2io.c patch1/drivers/net/s2io.c
--- orig/drivers/net/s2io.c	2007-12-21 12:10:29.000000000 -0800
+++ patch1/drivers/net/s2io.c	2007-12-21 13:36:59.000000000 -0800
@@ -50,6 +50,8 @@
  *                 Possible values '1' for enable , '0' for disable.
  *                 Default is '2' - which means disable in promisc mode
  *                 and enable in non-promiscuous mode.
+ * multiq: This parameter used to enable/disable MULTIQUEUE support.          *
+ *      Possible values '1' for enable and '0' for disable. Default is '0'    *
  ************************************************************************/
 
 #include <linux/module.h>
@@ -84,7 +86,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.15-2"
+#define DRV_VERSION "2.0.26.16"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -93,6 +95,12 @@ static char s2io_driver_version[] = DRV_
 static int rxd_size[2] = {32,48};
 static int rxd_count[2] = {127,85};
 
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+/* mapping from tos value to fifo number
+ * 0x0-0xF TOS values are mapped to 8 FIFOs */
+static int tos_map[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
+#endif
+
 static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
 {
 	int ret;
@@ -458,6 +466,7 @@ MODULE_VERSION(DRV_VERSION);
 /* Module Loadable parameters. */
 S2IO_PARM_INT(tx_fifo_num, 1);
 S2IO_PARM_INT(rx_ring_num, 1);
+S2IO_PARM_INT(multiq, 0);
 
 
 S2IO_PARM_INT(rx_ring_mode, 1);
@@ -533,6 +542,101 @@ static struct pci_driver s2io_driver = {
 /* A simplifier macro used both by init and free shared_mem Fns(). */
 #define TXD_MEM_PAGE_CNT(len, per_each) ((len+per_each - 1) / per_each)
 
+/* netqueue manipulation helper functions */
+static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp)
+{
+	int i;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (sp->config.multiq) {
+		for (i = 0; i < sp->config.tx_fifo_num; i++)
+			netif_stop_subqueue(sp->dev, i);
+	} else
+#endif
+	{
+		for (i = 0; i < sp->config.tx_fifo_num; i++)
+			sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP;
+		netif_stop_queue(sp->dev);
+	}
+}
+
+static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (sp->config.multiq)
+		netif_stop_subqueue(sp->dev, fifo_no);
+	else
+#endif
+	{
+		sp->mac_control.fifos[fifo_no].queue_state =
+			FIFO_QUEUE_STOP;
+		netif_stop_queue(sp->dev);
+	}
+}
+
+static inline void s2io_start_all_tx_queue(struct s2io_nic *sp)
+{
+	int i;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (sp->config.multiq) {
+		for (i = 0; i < sp->config.tx_fifo_num; i++)
+			netif_start_subqueue(sp->dev, i);
+	} else
+#endif
+	{
+		for (i = 0; i < sp->config.tx_fifo_num; i++)
+			sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
+		netif_start_queue(sp->dev);
+	}
+}
+
+static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (multiq)
+		netif_start_subqueue(sp->dev, fifo_no);
+	else
+#endif
+	{
+		sp->mac_control.fifos[fifo_no].queue_state =
+			FIFO_QUEUE_START;
+		netif_start_queue(sp->dev);
+	}
+}
+
+static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp)
+{
+	int i;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (sp->config.multiq) {
+			for (i = 0; i < sp->config.tx_fifo_num; i++)
+				netif_wake_subqueue(sp->dev, i);
+	} else
+#endif
+	{
+		for (i = 0; i < sp->config.tx_fifo_num; i++)
+			sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
+		netif_wake_queue(sp->dev);
+	}
+}
+
+static inline void s2io_wake_tx_queue(
+	struct fifo_info *fifo, int cnt, u8 multiq)
+{
+
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (multiq) {
+		if (cnt && __netif_subqueue_stopped(fifo->dev, fifo->fifo_no))
+			netif_wake_subqueue(fifo->dev, fifo->fifo_no);
+	} else
+#endif
+	if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) {
+		if (netif_queue_stopped(fifo->dev)) {
+			fifo->queue_state = FIFO_QUEUE_START;
+			netif_wake_queue(fifo->dev);
+		}
+	}
+}
+
 /**
  * init_shared_mem - Allocation and Initialization of Memory
  * @nic: Device private variable.
@@ -614,6 +718,7 @@ static int init_shared_mem(struct s2io_n
 		mac_control->fifos[i].fifo_no = i;
 		mac_control->fifos[i].nic = nic;
 		mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2;
+		mac_control->fifos[i].dev = dev;
 
 		for (j = 0; j < page_num; j++) {
 			int k = 0;
@@ -2975,10 +3080,10 @@ static void rx_intr_handler(struct ring_
 static void tx_intr_handler(struct fifo_info *fifo_data)
 {
 	struct s2io_nic *nic = fifo_data->nic;
-	struct net_device *dev = (struct net_device *) nic->dev;
 	struct tx_curr_get_info get_info, put_info;
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
 	struct TxD *txdlp;
+	int pkt_cnt = 0;
 	unsigned long flags = 0;
 	u8 err_mask;
 
@@ -3040,6 +3145,8 @@ static void tx_intr_handler(struct fifo_
 			return;
 		}
 
+		pkt_cnt++;
+
 		/* Updating the statistics block */
 		nic->stats.tx_bytes += skb->len;
 		nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
@@ -3054,8 +3161,7 @@ static void tx_intr_handler(struct fifo_
 		    get_info.offset;
 	}
 
-	if (netif_queue_stopped(dev))
-		netif_wake_queue(dev);
+	s2io_wake_tx_queue(fifo_data, pkt_cnt, nic->config.multiq);
 
 	spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
 }
@@ -3939,7 +4045,7 @@ static int s2io_open(struct net_device *
 		goto hw_init_failed;
 	}
 
-	netif_start_queue(dev);
+	s2io_start_all_tx_queue(sp);
 	return 0;
 
 hw_init_failed:
@@ -3985,7 +4091,7 @@ static int s2io_close(struct net_device 
 	if (!is_s2io_card_up(sp))
 		return 0;
 
-	netif_stop_queue(dev);
+	s2io_stop_all_tx_queue(sp);
 
 	/* delete all populated mac entries */
 	for (offset = 1; offset < config->max_mc_addr; offset++) {
@@ -4055,9 +4161,34 @@ static int s2io_xmit(struct sk_buff *skb
 		vlan_priority = vlan_tag >> 13;
 		queue = config->fifo_mapping[vlan_priority];
 	}
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	else if (skb->protocol == htons(ETH_P_IP) && sp->config.multiq) {
+		struct iphdr *ip;
+		ip = ip_hdr(skb);
+
+		/* get fifo number based on TOS value */
+		queue = tos_map[IPTOS_TOS(ip->tos) >> 1];
+	}
+#endif
 
 	fifo = &mac_control->fifos[queue];
 	spin_lock_irqsave(&fifo->tx_lock, flags);
+
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (sp->config.multiq) {
+		if (__netif_subqueue_stopped(dev, fifo->fifo_no)) {
+			spin_unlock_irqrestore(&fifo->tx_lock, flags);
+			return NETDEV_TX_BUSY;
+		}
+	} else
+#endif
+	if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) {
+		if (netif_queue_stopped(dev)) {
+			spin_unlock_irqrestore(&fifo->tx_lock, flags);
+			return NETDEV_TX_BUSY;
+		}
+	}
+
 	put_off = (u16) fifo->tx_curr_put_info.offset;
 	get_off = (u16) fifo->tx_curr_get_info.offset;
 	txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr;
@@ -4067,7 +4198,7 @@ static int s2io_xmit(struct sk_buff *skb
 	if (txdp->Host_Control ||
 		   ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
 		DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n");
-		netif_stop_queue(dev);
+		s2io_stop_tx_queue(sp, fifo->fifo_no);
 		dev_kfree_skb(skb);
 		spin_unlock_irqrestore(&fifo->tx_lock, flags);
 		return 0;
@@ -4173,7 +4304,7 @@ static int s2io_xmit(struct sk_buff *skb
 		DBG_PRINT(TX_DBG,
 			  "No free TxDs for xmit, Put: 0x%x Get:0x%x\n",
 			  put_off, get_off);
-		netif_stop_queue(dev);
+		s2io_stop_tx_queue(sp, fifo->fifo_no);
 	}
 	mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
 	dev->trans_start = jiffies;
@@ -4182,7 +4313,7 @@ static int s2io_xmit(struct sk_buff *skb
 	return 0;
 pci_map_failed:
 	stats->pci_map_fail_cnt++;
-	netif_stop_queue(dev);
+	s2io_stop_tx_queue(sp, fifo->fifo_no);
 	stats->mem_freed += skb->truesize;
 	dev_kfree_skb(skb);
 	spin_unlock_irqrestore(&fifo->tx_lock, flags);
@@ -4594,7 +4725,7 @@ static void s2io_handle_errors(void * de
 	return;
 
 reset:
-	netif_stop_queue(dev);
+	s2io_stop_all_tx_queue(sp);
 	schedule_work(&sp->rst_timer_task);
 	sw_stat->soft_reset_cnt++;
 	return;
@@ -6581,16 +6712,16 @@ static int s2io_change_mtu(struct net_de
 
 	dev->mtu = new_mtu;
 	if (netif_running(dev)) {
+		s2io_stop_all_tx_queue(sp);
 		s2io_card_down(sp);
-		netif_stop_queue(dev);
+
 		ret = s2io_card_up(sp);
 		if (ret) {
 			DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
 				  __FUNCTION__);
 			return ret;
 		}
-		if (netif_queue_stopped(dev))
-			netif_wake_queue(dev);
+		s2io_wake_all_tx_queue(sp);
 	} else { /* Device is down */
 		struct XENA_dev_config __iomem *bar0 = sp->bar0;
 		u64 val64 = new_mtu;
@@ -6698,7 +6829,7 @@ static void s2io_set_link(struct work_st
 			} else {
 				DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name);
 				DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
-				netif_stop_queue(dev);
+				s2io_stop_all_tx_queue(nic);
 			}
 		}
 		val64 = readq(&bar0->adapter_control);
@@ -7177,7 +7308,8 @@ static void s2io_restart_nic(struct work
 		DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
 			  dev->name);
 	}
-	netif_wake_queue(dev);
+	s2io_wake_all_tx_queue(sp);
+
 	DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n",
 		  dev->name);
 out_unlock:
@@ -7456,6 +7588,7 @@ static void s2io_link(struct s2io_nic * 
 		init_tti(sp, link);
 		if (link == LINK_DOWN) {
 			DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
+			s2io_stop_all_tx_queue(sp);
 			netif_carrier_off(dev);
 			if(sp->mac_control.stats_info->sw_stat.link_up_cnt)
 			sp->mac_control.stats_info->sw_stat.link_up_time =
@@ -7468,6 +7601,7 @@ static void s2io_link(struct s2io_nic * 
 				jiffies - sp->start_time;
 			sp->mac_control.stats_info->sw_stat.link_up_cnt++;
 			netif_carrier_on(dev);
+			s2io_wake_all_tx_queue(sp);
 		}
 	}
 	sp->last_link_state = link;
@@ -7504,7 +7638,8 @@ static void s2io_init_pci(struct s2io_ni
 	pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
 }
 
-static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
+static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
+	u8 *dev_multiq)
 {
 	if ((tx_fifo_num > MAX_TX_FIFOS) ||
 		(tx_fifo_num < FIFO_DEFAULT_NUM)) {
@@ -7518,6 +7653,19 @@ static int s2io_verify_parm(struct pci_d
 		DBG_PRINT(ERR_DBG, "tx fifos\n");
 	}
 
+#ifndef CONFIG_NETDEVICES_MULTIQUEUE
+	if (multiq) {
+		DBG_PRINT(ERR_DBG, "s2io: Multiqueue support not enabled\n");
+		multiq = 0;
+	}
+#endif
+
+	/* if multiqueue is enabled configure all fifos	*/
+	if (multiq) {
+		tx_fifo_num = MAX_TX_FIFOS;
+		*dev_multiq = multiq;
+	}
+
 	if ( rx_ring_num > 8) {
 		DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not "
 			 "supported\n");
@@ -7609,9 +7757,11 @@ s2io_init_nic(struct pci_dev *pdev, cons
 	struct config_param *config;
 	int mode;
 	u8 dev_intr_type = intr_type;
+	u8 dev_multiq = 0;
 	DECLARE_MAC_BUF(mac);
 
-	if ((ret = s2io_verify_parm(pdev, &dev_intr_type)))
+	ret = s2io_verify_parm(pdev, &dev_intr_type, &dev_multiq);
+	if (ret)
 		return ret;
 
 	if ((ret = pci_enable_device(pdev))) {
@@ -7643,7 +7793,13 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		return -ENODEV;
 	}
 
-	dev = alloc_etherdev(sizeof(struct s2io_nic));
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (dev_multiq)
+		dev = alloc_etherdev_mq(sizeof(struct s2io_nic), MAX_TX_FIFOS);
+	else
+#endif
+		dev = alloc_etherdev(sizeof(struct s2io_nic));
+
 	if (dev == NULL) {
 		DBG_PRINT(ERR_DBG, "Device allocation failed\n");
 		pci_disable_device(pdev);
@@ -7694,6 +7850,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
 
 	/* Tx side parameters. */
 	config->tx_fifo_num = tx_fifo_num;
+	config->multiq = dev_multiq;
 	for (i = 0; i < MAX_TX_FIFOS; i++) {
 		config->tx_cfg[i].fifo_len = tx_fifo_len[i];
 		config->tx_cfg[i].fifo_priority = i;
@@ -7807,6 +7964,11 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		dev->features |= NETIF_F_HW_CSUM;
 	}
 
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	if (config->multiq)
+		dev->features |= NETIF_F_MULTI_QUEUE;
+#endif
+
 	dev->tx_timeout = &s2io_tx_watchdog;
 	dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
 	INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
@@ -7963,6 +8125,16 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		    DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
 		    break;
 	}
+
+	if (sp->config.multiq) {
+		for (i = 0; i < sp->config.tx_fifo_num; i++)
+			mac_control->fifos[i].multiq = config->multiq;
+		DBG_PRINT(ERR_DBG, "%s: Multiqueue support enabled\n",
+			dev->name);
+	} else
+		DBG_PRINT(ERR_DBG, "%s: Multiqueue support disabled\n",
+			dev->name);
+
 	if (sp->lro)
 		DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
 			  dev->name);
diff -Nurp orig/drivers/net/s2io.h patch1/drivers/net/s2io.h
--- orig/drivers/net/s2io.h	2007-12-21 12:10:29.000000000 -0800
+++ patch1/drivers/net/s2io.h	2007-12-21 13:36:28.000000000 -0800
@@ -464,6 +464,7 @@ struct config_param {
 	int max_mc_addr;	/* xena=64 herc=256 */
 	int max_mac_addr;	/* xena=16 herc=64 */
 	int mc_start_offset;	/* xena=16 herc=64 */
+	u8 multiq;
 };
 
 /* Structure representing MAC Addrs */
@@ -721,6 +722,17 @@ struct fifo_info {
 	 */
 	struct tx_curr_get_info tx_curr_get_info;
 
+
+#define FIFO_QUEUE_START 0
+#define FIFO_QUEUE_STOP 1
+	int queue_state;
+
+	/* copy of sp->dev pointer */
+	struct net_device *dev;
+
+	/* copy of multiq status */
+	u8 multiq;
+
 	/* Per fifo lock */
 	spinlock_t tx_lock;
 
@@ -756,7 +768,7 @@ struct mac_info {
 	dma_addr_t stats_mem_phy;	/* Physical address of the stat block */
 	u32 stats_mem_sz;
 	struct stat_block *stats_info;	/* Logical address of the stat block */
-};
+} ____cacheline_aligned;
 
 /* structure representing the user defined MAC addresses */
 struct usr_addr {


^ permalink raw reply

* Re: [patch 7/7] netxen: fix byte-swapping in tx and rx
From: Al Viro @ 2007-12-26 23:53 UTC (permalink / raw)
  To: Dhananjay Phadke; +Cc: netdev, jeff
In-Reply-To: <Pine.LNX.4.64.0712261525490.23059@dut46.unminc.com>

On Wed, Dec 26, 2007 at 03:29:22PM -0800, Dhananjay Phadke wrote:
> I agree for tx desc, the compiler would optimize.
> 
> But for rx (status) desc, I didn't like multiple le64_to_cpu() 
> for extracting various fields out of same status dword.

Fair enough; AFAICS, on rx side you don't mess with conversion in
place and single le64_to_cpu() into a local variable is sane.

BTW,
+       u64 value = le64_to_cpu((status_desc)->status_desc_data); \
+       value &= ~(0x3ULL << 56); \
+       value |= (u64)(((u64)(val) << 56) & (0x3ULL << 56)); \  
+       (status_desc)->status_desc_data = cpu_to_le64(value); \
would be better off as
	status_desc->status_desc_data =
		status_desc->status_desc_data &
		cpu_to_le64(3ULL << 56) |
		cpu_to_le64(((u64)val & 3) << 56);
since the second term will be constant and you get one conversion instead
of two (and if val is constant, you'll get no conversions at all, just
one and + one or)

^ permalink raw reply

* Re : [RFC] old stuff - Kernel Bug Tracker Bug 7398
From: Pierre Ynard @ 2007-12-27  1:07 UTC (permalink / raw)
  To: Andreas Henriksson, netdev, David Miller; +Cc: 394780

> While looking over the old remaining bugs reported against iproute in
> Debian I came across http://bugs.debian.org/394780 which has also been
> reported as http://bugzilla.kernel.org/show_bug.cgi?id=7398 (please
> see the old comments here).
> [...]
> The bugs last comment was from Pierre asking about a patch he
> provided:
> > I am sorry, I didn't mean to break anything... What about a sysctl
> > option, to give the user the possibility to disable the hack? See
> > attached patch. I can't really see any drawback to that. Please
> > review and consider re-opening the bug.

This patch just by-passes the hack altogether. I haven't looked into the
details of what the hack does, nor do I know about vic or vat, so this
patch may not be the optimal solution. Anyway, I used it on my box, and
it did do the trick.

There must be other people who stumbled across this quirk. At the very
least, it should be clearly documented, where a sysadmin setting up
multicast streaming would find it.


-- 
Pierre Ynard
For hire - http://www.linkfanel.net/resume.pdf
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."



      _____________________________________________________________________________ 
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail http://mail.yahoo.fr

^ permalink raw reply

* Re: [PATCH] net/ipv4/netfilter/ip_tables.c: remove some inlines
From: Denys Vlasenko @ 2007-12-27  4:01 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: Harald Welte, netdev, linux-kernel,
	Netfilter Development Mailinglist
In-Reply-To: <47668BE9.8010504@trash.net>

On Monday 17 December 2007 14:47, Patrick McHardy wrote:
> Please CC netfilter-devel on netfilter patches.
>
> Denys Vlasenko wrote:
> > Hi Patrick, Harald,
> >
> > I was working on unrelated problem and noticed that ip_tables.c
> > seem to abuse inline. I prepared a patch which removes inlines
> > except those which are used by packet matching code
> > (and thus are really performance-critical).
> > I added comments explaining that remaining inlines are
> > performance critical.
> >
> > Result as reported by size:
> >
> >    text    data     bss     dec     hex filename
> > -  6451     380      88    6919    1b07 ip_tables.o
> > +  6339     348      72    6759    1a67 ip_tables.o
> >
> > Please take this patch into netfilter queue.
>
> This clashes with my pending patches, which I'll push upstream
> today. I also spent some time resyncing ip_tables and ip6_tables
> so a diff of both (with some sed'ing) shows only the actual
> differences, so please update ip6_tables as well.

I would be happy to rediff the patch.

Which tree should I sync against in order to not collide
with your changes?
--
vda

^ permalink raw reply

* Re: Strange Panic (Deadlock)
From: Jarek Poplawski @ 2007-12-27  7:19 UTC (permalink / raw)
  To: Badalian Vyacheslav; +Cc: netdev
In-Reply-To: <20071226185822.GC3061@ami.dom.local>

On 26-12-2007 19:58, Jarek Poplawski wrote:
> ...

And here is one more: this place needs more advanced debugging, but
let's check something simple at the beginning... (and just like before
- could be tested with or without these earlier patches).

Jarek P.
 
[PATCH 4/3] (for testing only)
---

diff -Nurp linux-2.6.23-/kernel/timer.c linux-2.6.23+/kernel/timer.c
--- linux-2.6.23-/kernel/timer.c	2007-10-09 22:31:38.000000000 +0200
+++ linux-2.6.23+/kernel/timer.c	2007-12-27 08:07:20.000000000 +0100
@@ -603,7 +603,10 @@ static int cascade(tvec_base_t *base, tv
 	 * don't have to detach them individually.
 	 */
 	list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
-		BUG_ON(tbase_get_base(timer->base) != base);
+		if (tbase_get_base(timer->base) != base) {
+			print_ip_sym((long)timer->function);
+			BUG_ON(1);
+		}
 		internal_add_timer(base, timer);
 	}
 

^ permalink raw reply

* fib6_del_route has redundant code
From: Gui Jianfeng @ 2007-12-27  7:26 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

Hi all,
I think the following code in fib6_del_route in the latest kernel is useless.
1125         if (fn->leaf == NULL && fn->fn_flags&RTN_TL_ROOT)
1126                 fn->leaf = &ip6_null_entry;

ip6_null_entry will never be unlinked from fn->leaf now, that is, fn->leaf == NULL will never meet.

In previous kernel, When adding a default route, ip6_null_entry will be unlinked from fn->leaf.
So, when deleting a default route, it need to check whether the deleted route is the last one,
if so, ip6_null_entry will link to fn->leaf again.

I am not sure if there is another place unlinks ip6_null_entry from fn->leaf.

Regards,
Gui Jiafeng

^ permalink raw reply

* Re: : Emit event stream compat iw_point objects correctly.
From: Masakazu Mokuno @ 2007-12-27  8:51 UTC (permalink / raw)
  To: David Miller
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20071221.205808.213484078.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>

	Hi

On Fri, 21 Dec 2007 20:58:08 -0800 (PST)
David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> wrote:

> @@ -520,7 +530,7 @@ iwe_stream_add_point(char *	stream,		/* Stream of events */
>  		memcpy(stream + IW_EV_LCP_LEN,
>  		       ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
>  		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);

As the alignment of 64bit platforms may be defferent from 32bit one,
should it be like the following?

static inline char *
iwe_stream_add_point(char *	stream,		/* Stream of events */
		     char *	ends,		/* End of stream */
		     struct iw_event *iwe,	/* Payload length + flags */
		     char *	extra,		/* More payload */
		     struct iw_request_info *info)
{
	int	event_len = IW_EV_POINT_LEN + iwe->u.data.length;
	int	point_len = IW_EV_POINT_LEN;
	int	lcp_len = IW_EV_LCP_LEN;

#ifdef CONFIG_COMPAT
	if (info->flags & IW_REQUEST_FLAG_COMPAT) {
		event_len = IW_EV_COMPAT_POINT_LEN + iwe->u.data.length;
		point_len = IW_EV_COMPAT_POINT_LEN;
		lcp_len = IW_EV_COMPAT_LCP_LEN;
	}
#endif

	/* Check if it's possible */
	if(likely((stream + event_len) < ends)) {
		iwe->len = event_len;
		memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
		memcpy(stream + lcp_len,
		       ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
		memcpy(stream + point_len, extra, iwe->u.data.length);
		stream += event_len;
	}
	return stream;
}

(Note that IW_EV_COMPAT_LCP_LEN is just a example; not defined anywhere)

-- 
Masakazu MOKUNO

^ permalink raw reply

* Re: : Emit event stream compat iw_point objects correctly.
From: David Miller @ 2007-12-27  8:57 UTC (permalink / raw)
  To: mokuno; +Cc: linux-wireless, netdev
In-Reply-To: <20071227173802.6F56.40F06B3A@sm.sony.co.jp>

From: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Date: Thu, 27 Dec 2007 17:51:49 +0900

> 	Hi
> 
> On Fri, 21 Dec 2007 20:58:08 -0800 (PST)
> David Miller <davem@davemloft.net> wrote:
> 
> > @@ -520,7 +530,7 @@ iwe_stream_add_point(char *	stream,		/* Stream of events */
> >  		memcpy(stream + IW_EV_LCP_LEN,
> >  		       ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
> >  		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
> 
> As the alignment of 64bit platforms may be defferent from 32bit one,
> should it be like the following?

IW_EV_LCP_LEN is the same on both 32-bit and 64-bit platforms, it is
just the size of the "len" and "cmd" portions of struct iw_event.

Those are both __u16, so IW_EV_LCP_LEN always evaluates to "4",
try it if you do not believe me. :-)

The iwreq_data size is invariant across the calculations.
If it's bigger on 64-bit, more will be subtracted in the
calculation performed by IW_EV_LCP_LEN.

So my patches are correct as-is and we do not need to
be mindful of compat'ness wrt. IW_EV_LCP_LEN.

^ permalink raw reply

* Re: : Emit event stream compat iw_point objects correctly.
From: Masakazu Mokuno @ 2007-12-27  9:24 UTC (permalink / raw)
  To: David Miller
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20071227.005725.144782426.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>


On Thu, 27 Dec 2007 00:57:25 -0800 (PST)
David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> wrote:

> From: Masakazu Mokuno <mokuno-DfbDroY8Xu1L9jVzuh4AOg@public.gmane.org>
> Date: Thu, 27 Dec 2007 17:51:49 +0900
> 
> > 	Hi
> > 
> > On Fri, 21 Dec 2007 20:58:08 -0800 (PST)
> > David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> wrote:
> > 
> > > @@ -520,7 +530,7 @@ iwe_stream_add_point(char *	stream,		/* Stream of events */
> > >  		memcpy(stream + IW_EV_LCP_LEN,
> > >  		       ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
> > >  		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
> > 
> > As the alignment of 64bit platforms may be defferent from 32bit one,
> > should it be like the following?
> 
> IW_EV_LCP_LEN is the same on both 32-bit and 64-bit platforms, it is
> just the size of the "len" and "cmd" portions of struct iw_event.
> 

IW_EV_LCP_PK_LEN ?

#define IW_EV_LCP_PK_LEN        (4)

> Those are both __u16, so IW_EV_LCP_LEN always evaluates to "4",
> try it if you do not believe me. :-)

Although I believed you, I tried :)

On ppc64 (PS3), IW_EV_LCP_LEN is 8, not 4.

include/linux/wireless.h:

#define IW_EV_LCP_LEN   (sizeof(struct iw_event) - sizeof(union iwreq_data))

where sizeof(struct iw_event) == 24, sizeof(union iwreq_data) == 16 on
PS3.

-- 
Masakazu MOKUNO

^ permalink raw reply

* Re: : Emit event stream compat iw_point objects correctly.
From: David Miller @ 2007-12-27  9:26 UTC (permalink / raw)
  To: mokuno-DfbDroY8Xu1L9jVzuh4AOg
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20071227181439.6F59.40F06B3A-DfbDroY8Xu1L9jVzuh4AOg@public.gmane.org>

From: Masakazu Mokuno <mokuno-DfbDroY8Xu1L9jVzuh4AOg@public.gmane.org>
Date: Thu, 27 Dec 2007 18:24:40 +0900

> On ppc64 (PS3), IW_EV_LCP_LEN is 8, not 4.
> 
> include/linux/wireless.h:
> 
> #define IW_EV_LCP_LEN   (sizeof(struct iw_event) - sizeof(union iwreq_data))
> 
> where sizeof(struct iw_event) == 24, sizeof(union iwreq_data) == 16 on
> PS3.

Hmmm, I will look into this, thank you :-)

^ permalink raw reply

* sunhme x86 SMP issues
From: Costa Tsaousis @ 2007-12-27  9:00 UTC (permalink / raw)
  To: netdev

Merry Christams,

I would like to report incompatibilities of the sunhme driver with x86 SMP.

My configuration:
Tyan S2466 motherboard with 2x Athlon MP 2400+
Kernel: 2.6.23-gentoo-r3

lscpi:
00:00.0 Host bridge: Advanced Micro Devices [AMD] AMD-760 MP [IGD4-2P] 
System Controller (rev 20)
00:01.0 PCI bridge: Advanced Micro Devices [AMD] AMD-760 MP [IGD4-2P] 
AGP Bridge
00:07.0 ISA bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] ISA (rev 05)
00:07.1 IDE interface: Advanced Micro Devices [AMD] AMD-768 [Opus] IDE 
(rev 04)
00:07.3 Bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] ACPI (rev 03)
00:08.0 Mass storage controller: Promise Technology, Inc. 20269 (rev 02)
00:09.0 Mass storage controller: Promise Technology, Inc. 20269 (rev 02)
00:10.0 PCI bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] PCI (rev 05)
01:05.0 VGA compatible controller: nVidia Corporation NV36.2 [GeForce FX 
5700] (rev a1)
02:00.0 USB Controller: Advanced Micro Devices [AMD] AMD-768 [Opus] USB 
(rev 07)
02:05.0 PCI bridge: Digital Equipment Corporation DECchip 21153 (rev 04)
02:06.0 Multimedia audio controller: Creative Labs SB Live! EMU10k1 (rev 08)
02:06.1 Input device controller: Creative Labs SB Live! Game Port (rev 08)
02:07.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8169 
Gigabit Ethernet (rev 10)
02:08.0 Ethernet controller: 3Com Corporation 3c905C-TX/TX-M [Tornado] 
(rev 78)
03:00.0 Bridge: Sun Microsystems Computer Corp. EBUS (rev 01)
03:00.1 Ethernet controller: Sun Microsystems Computer Corp. Happy Meal 
10/100 Ethernet [hme] (rev 01)
03:01.0 Bridge: Sun Microsystems Computer Corp. EBUS (rev 01)
03:01.1 Ethernet controller: Sun Microsystems Computer Corp. Happy Meal 
10/100 Ethernet [hme] (rev 01)
03:02.0 Bridge: Sun Microsystems Computer Corp. EBUS (rev 01)
03:02.1 Ethernet controller: Sun Microsystems Computer Corp. Happy Meal 
10/100 Ethernet [hme] (rev 01)
03:03.0 Bridge: Sun Microsystems Computer Corp. EBUS (rev 01)
03:03.1 Ethernet controller: Sun Microsystems Computer Corp. Happy Meal 
10/100 Ethernet [hme] (rev 01)

Sunhme (4 ports) and RTL-8169 (1 port) are configured as an Ethernet bridge.

The problem:
When transfering large files from one hme port to another, the machine 
temporarily freezes for a few seconds. Even the ssh sessions, the mouse, 
and the machine clock are completelly paused. After a few seconds the 
machine recovers without kernel errors or messages in most cases. These 
freezes appear continuously as far as the transfer is in place.

The problem relaxes a bit with 'noapic' but still happens.
The problem does not appear when the kernel is booted with maxcpus=0.
With maxcpus=1 the problem is that hme ports become almost unusable 
(like huge packet loss).

The problem does not appear when the machine is routing traffic from a 
non bridged Ethernet to an hme port.

I have tried several different kernel boot options and configurations, 
without founding any solution. Check this thread: 
http://forums.gentoo.org/viewtopic-t-635999-start-0-postdays-0-postorder-asc-highlight-.html?sid=275e5b2a0faea0c878b2a27fe7b83523

I am not subscribed to the list, so please CC me in replies.

Thanks,

Costa


^ permalink raw reply

* Re: Strange Panic (Deadlock)
From: Badalian Vyacheslav @ 2007-12-27 10:03 UTC (permalink / raw)
  To: Jarek Poplawski, netdev
In-Reply-To: <20071227071954.GA1670@ff.dom.local>

Jarek Poplawski пишет:
> On 26-12-2007 19:58, Jarek Poplawski wrote:
>   
>> ...
>>     
>
> And here is one more: this place needs more advanced debugging, but
> let's check something simple at the beginning... (and just like before
> - could be tested with or without these earlier patches).
>
> Jarek P.
>  
> [PATCH 4/3] (for testing only)
> ---
>
> diff -Nurp linux-2.6.23-/kernel/timer.c linux-2.6.23+/kernel/timer.c
> --- linux-2.6.23-/kernel/timer.c	2007-10-09 22:31:38.000000000 +0200
> +++ linux-2.6.23+/kernel/timer.c	2007-12-27 08:07:20.000000000 +0100
> @@ -603,7 +603,10 @@ static int cascade(tvec_base_t *base, tv
>  	 * don't have to detach them individually.
>  	 */
>  	list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
> -		BUG_ON(tbase_get_base(timer->base) != base);
> +		if (tbase_get_base(timer->base) != base) {
> +			print_ip_sym((long)timer->function);
> +			BUG_ON(1);
> +		}
>  		internal_add_timer(base, timer);
>  	}
>  
>
>   
Hello
I add bugreport
http://bugzilla.kernel.org/show_bug.cgi?id=9632
/Oleg Nesterov <mailto:oleg@tv-sign.ru> give me patch to debug
bugplace... its look stable and i try it in few days...
Slavon
/

^ permalink raw reply

* [PATCH 2.6.25] compilation fix for drivers/net/wireless/libertas/debugfs.c (fixed signed-off)
From: Denis V. Lunev @ 2007-12-27 10:35 UTC (permalink / raw)
  To: davem; +Cc: devel, mchan, netdev

Compilation fix. MAC_FMT is required for
drivers/net/wireless/libertas/debugfs.c

The problem has been introduced by the
commit 4b326fa2167d4ee2d722bff4e241fae299e32442
Author: Michael Chan <mchan@broadcom.com>
Date:   Mon Dec 24 21:28:09 2007 -0800

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 7a1e011..2928586 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -129,6 +129,7 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
 /*
  *	Display a 6 byte device address (MAC) in a readable format.
  */
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
 extern char *print_mac(char *buf, const unsigned char *addr);
 #define MAC_BUF_SIZE	18
 #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused

^ permalink raw reply related

* [PATCH 2.6.25] compilation fix for drivers/net/wireless/libertas/debugfs.c
From: Denis V. Lunev @ 2007-12-27 10:24 UTC (permalink / raw)
  To: davem; +Cc: devel, mchan, netdev

Compilation fix. MAC_FMT is required for
drivers/net/wireless/libertas/debugfs.c

The problem has been introduced by the
commit 4b326fa2167d4ee2d722bff4e241fae299e32442
Author: Michael Chan <mchan@broadcom.com>
Date:   Mon Dec 24 21:28:09 2007 -0800

diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 7a1e011..2928586 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -129,6 +129,7 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
 /*
  *	Display a 6 byte device address (MAC) in a readable format.
  */
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
 extern char *print_mac(char *buf, const unsigned char *addr);
 #define MAC_BUF_SIZE	18
 #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused

^ permalink raw reply related


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