* Re: [PATCH][KS8695] Mark network interface as running on ifconfig up
From: David Miller @ 2010-02-26 9:20 UTC (permalink / raw)
To: yegor_sub1; +Cc: linux-arm-kernel, avictor.za, netdev
In-Reply-To: <4B82A72E.50508@visionsystems.de>
From: Yegor Yefremov <yegor_sub1@visionsystems.de>
Date: Mon, 22 Feb 2010 16:47:58 +0100
> [KS8695] Don't call netif_carrier_off() from ndo_stop()
>
> netif_carrier_on() and netif_carrier_off() should be called from
> link status interrupt handler
>
> Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
Looks good, applied.
Please do not put text you want to make it into the
commit message header line in brackets "[]", those
get removed by automated tools that apply patches
because patches are usually posted as:
Subject: [PATCH N/M] xxxx
and the GIT tools kill all the text inside of the brackets
so that the commit header properly reads "xxx"
Thanks.
^ permalink raw reply
* Re: [PATCH 5/5] net: sock_aio_write: set CMSG_MSG_COMPAT flag if is_compat_task
From: David Miller @ 2010-02-26 9:17 UTC (permalink / raw)
To: fwestphal; +Cc: netdev, johannes
In-Reply-To: <20100226.011646.257642830.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Fri, 26 Feb 2010 01:16:46 -0800 (PST)
> From: Florian Westphal <fwestphal@astaro.com>
> Date: Fri, 19 Feb 2010 13:41:47 +0100
>
>> @@ -837,6 +837,10 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
>> msg->msg_iov = (struct iovec *)iov;
>> msg->msg_iovlen = nr_segs;
>> msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
>> +#ifdef CONFIG_COMPAT
>> + if (is_compat_task())
>> + msg->msg_flags |= MSG_CMSG_COMPAT;
>> +#endif
>> if (sock->type == SOCK_SEQPACKET)
>> msg->msg_flags |= MSG_EOR;
>>
>
> What if the kernel itself does a socket write, say from a software
> interrupt or to generate events in response to a user event,
> and the current process happens to be a compat task?
BTW, it's again another example of why is_compat_task() is almost
always the wrong thing to use.
^ permalink raw reply
* Re: [PATCH 5/5] net: sock_aio_write: set CMSG_MSG_COMPAT flag if is_compat_task
From: David Miller @ 2010-02-26 9:16 UTC (permalink / raw)
To: fwestphal; +Cc: netdev, johannes
In-Reply-To: <1266583307-3049-6-git-send-email-fwestphal@astaro.com>
From: Florian Westphal <fwestphal@astaro.com>
Date: Fri, 19 Feb 2010 13:41:47 +0100
> some programs (e.g. pluto ike daemon), send netlink data to the
> kernel via write().
>
> So far, the CMSG_MSG_COMPAT flag is not set in this case, which
> results in the kernel interpreting the netlink data the wrong way.
>
> An alternative solution is to switch userspace to sendmsg() when
> using netlink sockets.
>
> Cc: Johannes Berg <johannes@sipsolutions.net>
> Signed-off-by: Florian Westphal <fwestphal@astaro.com>
I was about to apply this entire patch set, but thinking about this
one patch we have to do it differently:
> @@ -837,6 +837,10 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
> msg->msg_iov = (struct iovec *)iov;
> msg->msg_iovlen = nr_segs;
> msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
> +#ifdef CONFIG_COMPAT
> + if (is_compat_task())
> + msg->msg_flags |= MSG_CMSG_COMPAT;
> +#endif
> if (sock->type == SOCK_SEQPACKET)
> msg->msg_flags |= MSG_EOR;
>
What if the kernel itself does a socket write, say from a software
interrupt or to generate events in response to a user event,
and the current process happens to be a compat task?
I think this could even occur for NFS perhaps?
Anyways, that isn't going to work properly.
We might need to add ->compat_write to file operations to do
it properly.
^ permalink raw reply
* [net-next-2.6 PATCH 3/3] ixgbe: Do not allocate too many netdev txqueues
From: Jeff Kirsher @ 2010-02-26 9:15 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, John Fastabend, Jeff Kirsher
In-Reply-To: <20100226091318.19796.70225.stgit@localhost.localdomain>
From: John Fastabend <john.r.fastabend@intel.com>
Instead of allocating 128 struct netdev_queue per device, use the
minimum value between 128 and the number of possible txq's, to
reduce ram usage and "tc -s -d class shod dev .." output.
This patch fixes Eric Dumazet's patch to set the TX queues to
the correct minimum.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_main.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 4a01022..a961da2 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -5996,6 +5996,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
static int cards_found;
int i, err, pci_using_dac;
+ unsigned int indices = num_possible_cpus();
#ifdef IXGBE_FCOE
u16 device_caps;
#endif
@@ -6034,7 +6035,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
pci_set_master(pdev);
pci_save_state(pdev);
- netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES);
+ if (ii->mac == ixgbe_mac_82598EB)
+ indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
+ else
+ indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES);
+
+ indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES);
+#ifdef IXGBE_FCOE
+ indices += min_t(unsigned int, num_possible_cpus(),
+ IXGBE_MAX_FCOE_INDICES);
+#endif
+ indices = min_t(unsigned int, indices, MAX_TX_QUEUES);
+ netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
if (!netdev) {
err = -ENOMEM;
goto err_alloc_etherdev;
^ permalink raw reply related
* [net-next-2.6 PATCH 2/3] ixgbe: do not stop tx queues in ixgbe_set_tso
From: Jeff Kirsher @ 2010-02-26 9:14 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, John Fastabend, Peter P Waskiewicz Jr,
Jeff Kirsher
In-Reply-To: <20100226091318.19796.70225.stgit@localhost.localdomain>
From: John Fastabend <john.r.fastabend@intel.com>
Disabling TSO can cause the dev_watchdog timer to be triggered because
when TSO is disabled netif_tx_stop_all_queues is called. If the watchdog
timer fires while the queues are stopped and traffic has not recently been
sent on a paticular queue this is falsly identified as a hang and
ndo_tx_timeout() is called. This is ocossionally seen during testing.
This removes the netif_tx_stop_all_queues() it is not needed. The scheduler
submits skb's with dev_hard_start_xmit(), this checks if netif_needs_gso and
if so it calls dev_gso_segment. Disabling TSO will cause dev_hard_start_xmit()
to do the gso processing. However ixgbe does not use the features flags to
determine if it needs to use tso or not instead it uses skb->gso_size so
ixgbe will process these frames correctly regardless of the netdev features
flag.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_ethtool.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 0d23434..7949a44 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -441,10 +441,8 @@ static int ixgbe_set_tso(struct net_device *netdev, u32 data)
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
} else {
- netif_tx_stop_all_queues(netdev);
netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6;
- netif_tx_start_all_queues(netdev);
}
return 0;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 1/3] ixgbe: Fix DMA mapping/unmapping issues when HWRSC is enabled on IOMMU enabled kernels
From: Jeff Kirsher @ 2010-02-26 9:14 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Mallikarjuna R Chilakala, Jeff Kirsher
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Work around 82599 HW issue when HWRSC is enabled on IOMMU enabled
kernels. 82599 HW is updating the header information after setting the
descriptor to done, resulting DMA mapping/unmapping issues on IOMMU
enabled systems. To work around the issue delay unmapping of first packet
that carries the header information until end of packet is reached.
Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_main.c | 32 +++++++++++++++++++++++++++++---
1 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 3308790..4a01022 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -818,6 +818,12 @@ static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb,
return skb;
}
+struct ixgbe_rsc_cb {
+ dma_addr_t dma;
+};
+
+#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb)
+
static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
int *work_done, int work_to_do)
@@ -867,9 +873,21 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
rx_buffer_info->skb = NULL;
if (rx_buffer_info->dma) {
- pci_unmap_single(pdev, rx_buffer_info->dma,
- rx_ring->rx_buf_len,
- PCI_DMA_FROMDEVICE);
+ if ((adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
+ (!(staterr & IXGBE_RXD_STAT_EOP)) &&
+ (!(skb->prev)))
+ /*
+ * When HWRSC is enabled, delay unmapping
+ * of the first packet. It carries the
+ * header information, HW may still
+ * access the header after the writeback.
+ * Only unmap it when EOP is reached
+ */
+ IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma;
+ else
+ pci_unmap_single(pdev, rx_buffer_info->dma,
+ rx_ring->rx_buf_len,
+ PCI_DMA_FROMDEVICE);
rx_buffer_info->dma = 0;
skb_put(skb, len);
}
@@ -917,6 +935,10 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (skb->prev)
skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
+ if (IXGBE_RSC_CB(skb)->dma)
+ pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma,
+ rx_ring->rx_buf_len,
+ PCI_DMA_FROMDEVICE);
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;
else
@@ -3104,6 +3126,10 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info->skb = NULL;
do {
struct sk_buff *this = skb;
+ if (IXGBE_RSC_CB(this)->dma)
+ pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma,
+ rx_ring->rx_buf_len,
+ PCI_DMA_FROMDEVICE);
skb = skb->prev;
dev_kfree_skb(this);
} while (skb);
^ permalink raw reply related
* Re: [PATCH v2 0/3] e1000e, igb, ixgbe: add registers etc. printout code just before resetting adapters
From: Taku Izumi @ 2010-02-26 9:05 UTC (permalink / raw)
To: Brandeburg, Jesse
Cc: Koki Sanagi, e1000-devel@lists.sourceforge.net,
netdev@vger.kernel.org, Allan, Bruce W, chavey@google.com,
Ronciak, John, Kirsher, Jeffrey T, Kenji Kaneshige,
David S. Miller
In-Reply-To: <alpine.WNT.2.00.1002171043450.5328@jbrandeb-desk1.amr.corp.intel.com>
Hi Jesse,
(2010/02/18 4:10), Brandeburg, Jesse wrote:
>
> On Tue, 26 Jan 2010, Taku Izumi wrote:
>> (2010/01/23 6:54), Brandeburg, Jesse wrote:
>>> Taku, thanks for these, we are talking the patches over and reviewing
>>> them. While I agree with the idea of these patches is good, I still don't
>>> agree with the default being enabled. Usually if someone is getting tx
>>> hangs they are repeatable and we can work with them to get the debug
>>> turned on. I DO think it is useful to have the feature available by
>>> default but NOT enabled.
>>>
>>> If we wanted to enable something by default it might be useful to print
>>> something that actually draws some conclusions from known failure modes,
>>> like if TDH!=TDT after some amount of time. I think one or two lines
>>> maximum for default printing.
>>>
>>> If you're working in this area I had an idea. I had wanted to be able to
>>> print the large amount of ring information (especially in the ixgbe case
>>> with many rings) to the ftrace buffers in order to not overrun the syslog
>>> daemon. Not sure if you're interested in more new features, it certainly
>>> is separate but related to this patch.
>>
>> I thought similar things, that is, all information should be dumped to
>> the private ring buffer to avoid filling syslog up with driver messages.
>> But I didn't have any good idea to extract information from ring buffers,
>> so as the first step, I decided to printout it by using printk().
>> Is there the easy way to extract it from ring buffers?
>
> First, I need to apologize for the delay, it's my fault.
>
> I'm not sure about an easy way to use the private ring buffers yet, I know
> you can use the ftrace buffers directly, and then when someone read
> /sys/kernel/debug/tracing/trace they would get all the output.
>
> Lets not do ftrace yet.
>
> I have a counter proposal to make, here is a (incomplete) patch that we
> use all the time to debug tx hangs. This example is for e1000e. We are
> trying to avoid changes with other users' copyright to some of the files
> in our drivers so that we can ship them under multiple license. We would
> much prefer something like this to be used, can you review?
>
> I also have another patch I made for ixgb to show the use of sysfs and a
> module parameter, I'll reply again with that next.
>
> ---
> From: Jesse Brandeburg<jesse.brandeburg@intel.com>
>
> e1000e: dump code for descriptor rings
>
> This is debug code for descriptor ring dumps, only enable if you really want a
> lot of stuff in your syslog/dmesg when you get NETDEV WATCHDOG or tx hang
> reports from the driver.
>
> <not implemented> Code can be enabled at boot time with a module parameter or
> via sysfs at runtime.
>
> Signed-off-by: Jesse Brandeburg<jesse.brandeburg@intel.com>
> ---
>
> drivers/net/e1000e/ethtool.c | 4 +
> drivers/net/e1000e/hw.h | 10 +
> drivers/net/e1000e/netdev.c | 298 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 311 insertions(+), 1 deletions(-)
>
>
> diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
> index 0aa50c2..bbcf5c7 100644
> --- a/drivers/net/e1000e/ethtool.c
> +++ b/drivers/net/e1000e/ethtool.c
> @@ -434,6 +434,8 @@ static int e1000_get_regs_len(struct net_device *netdev)
> return E1000_REGS_LEN * sizeof(u32);
> }
>
> +extern void e1000e_dump(struct e1000_adapter *);
> +
> static void e1000_get_regs(struct net_device *netdev,
> struct ethtool_regs *regs, void *p)
> {
> @@ -443,6 +445,8 @@ static void e1000_get_regs(struct net_device *netdev,
> u16 phy_data;
> u8 revision_id;
>
> + e1000e_dump(adapter);
> +
> memset(p, 0, E1000_REGS_LEN * sizeof(u32));
>
> pci_read_config_byte(adapter->pdev, PCI_REVISION_ID,&revision_id);
> diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
> index eccf29b..d23501d 100644
> --- a/drivers/net/e1000e/hw.h
> +++ b/drivers/net/e1000e/hw.h
> @@ -92,6 +92,11 @@ enum e1e_registers {
> E1000_FCRTL = 0x02160, /* Flow Control Receive Threshold Low - RW */
> E1000_FCRTH = 0x02168, /* Flow Control Receive Threshold High - RW */
> E1000_PSRCTL = 0x02170, /* Packet Split Receive Control - RW */
> + E1000_RDFH = 0x02410, /* Rx Data FIFO Head - RW */
> + E1000_RDFT = 0x02418, /* Rx Data FIFO Tail - RW */
> + E1000_RDFHS = 0x02420, /* Rx Data FIFO Head Saved - RW */
> + E1000_RDFTS = 0x02428, /* Rx Data FIFO Tail Saved - RW */
> + E1000_RDFPC = 0x02430, /* Rx Data FIFO Packet Count - RW */
> E1000_RDBAL = 0x02800, /* Rx Descriptor Base Address Low - RW */
> E1000_RDBAH = 0x02804, /* Rx Descriptor Base Address High - RW */
> E1000_RDLEN = 0x02808, /* Rx Descriptor Length - RW */
> @@ -112,6 +117,11 @@ enum e1e_registers {
> */
> #define E1000_RDBAL_REG(_n) (E1000_RDBAL + (_n<< 8))
> E1000_KABGTXD = 0x03004, /* AFE Band Gap Transmit Ref Data */
> + E1000_TDFH = 0x03410, /* TX Data FIFO Head - RW */
> + E1000_TDFT = 0x03418, /* TX Data FIFO Tail - RW */
> + E1000_TDFHS = 0x03420, /* TX Data FIFO Head Saved - RW */
> + E1000_TDFTS = 0x03428, /* Tx Data FIFO Tail Saved - RW */
> + E1000_TDFPC = 0x03430, /* TX Data FIFO Packet Count - RW */
> E1000_TDBAL = 0x03800, /* Tx Descriptor Base Address Low - RW */
> E1000_TDBAH = 0x03804, /* Tx Descriptor Base Address High - RW */
> E1000_TDLEN = 0x03808, /* Tx Descriptor Length - RW */
> diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
> index c45965a..c990341 100644
> --- a/drivers/net/e1000e/netdev.c
> +++ b/drivers/net/e1000e/netdev.c
> @@ -48,7 +48,7 @@
>
> #include "e1000.h"
>
> -#define DRV_VERSION "1.0.2-k2"
> +#define DRV_VERSION "1.0.2-k4"
> char e1000e_driver_name[] = "e1000e";
> const char e1000e_driver_version[] = DRV_VERSION;
>
> @@ -601,6 +601,301 @@ static void e1000_print_hw_hang(struct work_struct *work)
> pci_status);
> }
>
> +#if 0
> +static void hexdump(dma_addr_t dma, u16 len)
> +{
> + u16 offset, i;
> + char str[80], byte[4];
> + void *va = phys_to_virt((unsigned long)dma);
> +
> + printk("buffer at %016llX (%d)\n", (u64)dma, len);
> + for (offset = 0; offset< len; offset += 16) {
> + sprintf(str, "%04x: ", offset);
> + for (i = 0; i< 16; i++) {
> + if ((offset + i)< len)
> + sprintf(byte, "%02x ",
> + ((unsigned char *)va)[offset + i]);
> + else
> + strcpy(byte, " ");
> + strcat(str, byte);
> + }
> + printk("%s\n", str);
> + }
> +}
> +
> +#endif
> +void e1000e_dump(struct e1000_adapter *adapter)
> +{
> + /* this code doesn't handle multiple rings */
> + struct e1000_ring *tx_ring = adapter->tx_ring;
> + struct e1000_ring *rx_ring = adapter->rx_ring;
> + struct e1000_hw *hw =&adapter->hw;
> + int i = 0;
> +#define NUM_REGS 38 /* 1 based count */
> + u32 regs[NUM_REGS];
> + u32 *regs_buff = regs;
> +
> + char *reg_name[] = {
> + "CTRL", "STATUS",
> + "RCTL", "RDLEN", "RDH", "RDT", "RDTR",
> + "TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT",
> + "TIDV", "TXDCTL", "TADV", "TARC0",
> + "TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1",
> + "TXDCTL1", "TARC1",
> + "CTRL_EXT", "ERT", "RDBAL", "RDBAH",
> + "TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC",
> + "RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC",
> + };
> +
> + //if (!e1000e_debug_dump)
> + //return;
> +
> + regs_buff[0] = er32(CTRL);
> + regs_buff[1] = er32(STATUS);
> +
> + regs_buff[2] = er32(RCTL);
> + regs_buff[3] = er32(RDLEN);
> + regs_buff[4] = er32(RDH);
> + regs_buff[5] = er32(RDT);
> + regs_buff[6] = er32(RDTR);
> +
> + regs_buff[7] = er32(TCTL);
> + regs_buff[8] = er32(TDBAL);
> + regs_buff[9] = er32(TDBAH);
> + regs_buff[10] = er32(TDLEN);
> + regs_buff[11] = er32(TDH);
> + regs_buff[12] = er32(TDT);
> + regs_buff[13] = er32(TIDV);
> + regs_buff[14] = er32(TXDCTL(0));
> + regs_buff[15] = er32(TADV);
> + regs_buff[16] = er32(TARC(0));
> +
> + regs_buff[22] = er32(TXDCTL(1));
> + regs_buff[23] = er32(TARC(1));
> + regs_buff[24] = er32(CTRL_EXT);
> + regs_buff[25] = er32(ERT);
> + regs_buff[26] = er32(RDBAL);
> + regs_buff[27] = er32(RDBAH);
> + regs_buff[28] = er32(TDFH);
> + regs_buff[29] = er32(TDFT);
> + regs_buff[30] = er32(TDFHS);
> + regs_buff[31] = er32(TDFTS);
> + regs_buff[32] = er32(TDFPC);
> + regs_buff[33] = er32(RDFH);
> + regs_buff[34] = er32(RDFT);
> + regs_buff[35] = er32(RDFHS);
> + regs_buff[36] = er32(RDFTS);
> + regs_buff[37] = er32(RDFPC);
I think indexing is annoying especially when the number of registers
is large for example in case of the ixgbe driver.
> +
> + e_err("Register dump\n");
> + for (i = 0; i< NUM_REGS; i++) {
> + printk("%-15s %08x\n",
> + reg_name[i], regs_buff[i]);
> + }
> +
> + /*
> + * transmit dump
> + */
> + printk(KERN_ERR"TX Desc ring0 dump\n");
> +
> + /* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
> + *
> + * Legacy Transmit Descriptor
> + * +--------------------------------------------------------------+
> + * 0 | Buffer Address [63:0] (Reserved on Write Back) |
> + * +--------------------------------------------------------------+
> + * 8 | Special | CSS | Status | CMD | CSO | Length |
> + * +--------------------------------------------------------------+
> + * 63 48 47 36 35 32 31 24 23 16 15 0
> + *
> + * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
> + * 63 48 47 40 39 32 31 16 15 8 7 0
> + * +----------------------------------------------------------------+
> + * 0 | TUCSE | TUCS0 | TUCSS | IPCSE | IPCS0 | IPCSS |
> + * +----------------------------------------------------------------+
> + * 8 | MSS | HDRLEN | RSV | STA | TUCMD | DTYP | PAYLEN |
> + * +----------------------------------------------------------------+
> + * 63 48 47 40 39 36 35 32 31 24 23 20 19 0
> + *
> + * Extended Data Descriptor (DTYP=0x1)
> + * +----------------------------------------------------------------+
> + * 0 | Buffer Address [63:0] |
> + * +----------------------------------------------------------------+
> + * 8 | VLAN tag | POPTS | Rsvd | Status | Command | DTYP | DTALEN |
> + * +----------------------------------------------------------------+
> + * 63 48 47 40 39 36 35 32 31 24 23 20 19 0
> + */
> + printk("Tl(Legacy) [address 63:0 ] [SpeCssSCmCsLen] [buffer_info dma"
> + " leng ntw time_stamp skb]\n");
> + printk("Tc(ExtCont) [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [buffer_info dma"
> + " leng ntw time_stamp skb]\n");
> + printk("Td(ExtData) [address 63:0 ] [VlaPoRSCm1Dlen] [buffer_info dma"
> + " leng ntw time_stamp skb]\n");
> + for (i = 0; tx_ring->desc&& (i< tx_ring->count); i++) {
> + struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
> + struct e1000_buffer *buffer_info =&tx_ring->buffer_info[i];
> + struct my_u { u64 a; u64 b; };
> + struct my_u *u = (struct my_u *)tx_desc;
> + printk("T%c[0x%03X] %016llX %016llX %016llX %04X %3X "
> + "%016llX %p",
> + (!(le64_to_cpu(u->b)& (1<<29)) ? 'l' :
> + ((le64_to_cpu(u->b)& (1<<20)) ? 'd' : 'c')), i,
> + le64_to_cpu(u->a), le64_to_cpu(u->b),
> + (u64)buffer_info->dma, buffer_info->length,
> + buffer_info->next_to_watch, (u64)buffer_info->time_stamp,
> + buffer_info->skb);
> + if (i == tx_ring->next_to_use&& i == tx_ring->next_to_clean)
> + printk(" NTC/U\n");
> + else if (i == tx_ring->next_to_use)
> + printk(" NTU\n");
> + else if (i == tx_ring->next_to_clean)
> + printk(" NTC\n");
> + else
> + printk("\n");
> +
> +#if 0
> + if (adapter->dump_buffers&& (buffer_info->dma != 0))
> + hexdump(buffer_info->dma, buffer_info->length);
> +#endif
> + }
> +
> + /*
> + * receive dump
> + */
> + printk(KERN_ERR"\nRX Desc ring dump\n");
> +
> + switch (adapter->rx_ps_pages) {
> + case 1:
> + case 2:
> + case 3:
> + /* [Extended] Packet Split Receive Descriptor Format
> + *
> + * +-----------------------------------------------------+
> + * 0 | Buffer Address 0 [63:0] |
> + * +-----------------------------------------------------+
> + * 8 | Buffer Address 1 [63:0] |
> + * +-----------------------------------------------------+
> + * 16 | Buffer Address 2 [63:0] |
> + * +-----------------------------------------------------+
> + * 24 | Buffer Address 3 [63:0] |
> + * +-----------------------------------------------------+
> + */
> + printk("R [desc] [buffer 0 63:0 ] [buffer 1 63:0 ] "
> + "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma ] "
> + "[bi->skb]<-- Ext Pkt Split format\n");
> + /* [Extended] Receive Descriptor (Write-Back) Format
> + *
> + * 63 48 47 32 31 13 12 8 7 4 3 0
> + * +------------------------------------------------------+
> + * 0 | Packet | IP | Rsvd | MRQ | Rsvd | MRQ RSS |
> + * | Checksum | Ident | | Queue | | Type |
> + * +------------------------------------------------------+
> + * 8 | VLAN Tag | Length | Extended Error | Extended Status |
> + * +------------------------------------------------------+
> + * 63 48 47 32 31 20 19 0
> + */
> + printk("RWB[desc] [ck ipid mrqhsh] [vl l0 ee es] "
> + "[ l3 l2 l1 hs] [reserved ] ---------------- "
> + "[bi->skb]<-- Ext Rx Write-Back format\n");
> + for (i = 0; i< rx_ring->count; i++) {
> + struct e1000_buffer *buffer_info =
> + &rx_ring->buffer_info[i];
> + union e1000_rx_desc_packet_split *rx_desc =
> + E1000_RX_DESC_PS(*rx_ring, i);
> + struct my_u { u64 a; u64 b; u64 c; u64 d; };
> + struct my_u *u = (struct my_u *)rx_desc;
> + u32 staterr;
> + staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
> + if (staterr& E1000_RXD_STAT_DD) {
> + /* Descriptor Done */
> + printk("RWB[0x%03X] %016llX %016llX %016llX"
> + " %016llX ---------------- %p",
> + i, le64_to_cpu(u->a), le64_to_cpu(u->b),
> + le64_to_cpu(u->c), le64_to_cpu(u->d),
> + buffer_info->skb);
> + } else {
> + printk("R [0x%03X] %016llX %016llX %016llX"
> + " %016llX %016llX %p",
> + i, le64_to_cpu(u->a), le64_to_cpu(u->b),
> + le64_to_cpu(u->c), le64_to_cpu(u->d),
> + (u64)buffer_info->dma, buffer_info->skb);
> +
> +#if 0
> + if (adapter->dump_buffers)
> + hexdump(buffer_info->dma,
> + adapter->rx_ps_bsize0);
> +#endif
> + }
> +
> + if (i == rx_ring->next_to_use)
> + printk(" NTU\n");
> + else if (i == rx_ring->next_to_clean)
> + printk(" NTC\n");
> + else
> + printk("\n");
> + }
> + break;
> + default:
> + case 0:
> + /* Legacy Receive Descriptor Format
> + *
> + * +-----------------------------------------------------+
> + * | Buffer Address [63:0] |
> + * +-----------------------------------------------------+
> + * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
> + * +-----------------------------------------------------+
> + * 63 48 47 40 39 32 31 16 15 0
> + */
> + printk("Rl[desc] [address 63:0 ] [vl er S cks ln] "
> + "[bi->dma ] [bi->skb]<-- Legacy format\n");
> + for (i = 0; rx_ring->desc&& (i< rx_ring->count); i++) {
> + struct e1000_rx_desc *rx_desc =
> + E1000_RX_DESC(*rx_ring, i);
> + struct e1000_buffer *buffer_info =
> + &rx_ring->buffer_info[i];
> + struct my_u { u64 a; u64 b; };
> + struct my_u *u = (struct my_u *)rx_desc;
> + printk("Rl[0x%03X] %016llX %016llX %016llX %p",
> + i, le64_to_cpu(u->a), le64_to_cpu(u->b),
> + (u64)buffer_info->dma, buffer_info->skb);
> + if (i == rx_ring->next_to_use)
> + printk(" NTU\n");
> + else if (i == rx_ring->next_to_clean)
> + printk(" NTC\n");
> + else
> + printk("\n");
> +
> +#if 0
> + if (adapter->dump_buffers)
> + hexdump(buffer_info->dma,
> + adapter->rx_buffer_len);
> +#endif
> + } /* for */
> + } /* switch */
> +
> + /* dump the descriptor caches */
> + /* rx */
> + printk("Rx descriptor cache in 64bit format\n");
> + for (i = 0x6000; i<= 0x63FF ; i += 0x10) {
> + printk("R%04X: %08X|%08X %08X|%08X\n",
> + i,
> + readl(adapter->hw.hw_addr + i+4),
> + readl(adapter->hw.hw_addr + i),
> + readl(adapter->hw.hw_addr + i+12),
> + readl(adapter->hw.hw_addr + i+8));
> + }
> + /* tx */
> + printk("Tx descriptor cache in 64bit format\n");
> + for (i = 0x7000; i<= 0x73FF ; i += 0x10) {
> + printk("T%04X: %08X|%08X %08X|%08X\n",
> + i,
> + readl(adapter->hw.hw_addr + i+4),
> + readl(adapter->hw.hw_addr + i),
> + readl(adapter->hw.hw_addr + i+12),
> + readl(adapter->hw.hw_addr + i+8));
> + }
> +}
> +
> /**
> * e1000_clean_tx_irq - Reclaim resources after transmit completes
> * @adapter: board private structure
> @@ -682,6 +977,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
> + (adapter->tx_timeout_factor * HZ))&&
> !(er32(STATUS)& E1000_STATUS_TXOFF)) {
> schedule_work(&adapter->print_hang_task);
> + e1000e_dump(adapter);
I think it is not proper to invoke e1000e_dump() here because here is in interupt
context and there is the case of resetting adapters without meeting the condition
of "adapter->detect_tx_hung == true"
> netif_stop_queue(netdev);
> }
> }
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
Best regards,
Taku Izumi
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2010-02-22
From: David Miller @ 2010-02-26 7:27 UTC (permalink / raw)
To: linville-2XuSBdqkA4R54TAoqtyWWQ
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20100222185638.GC2988-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
From: "John W. Linville" <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Date: Mon, 22 Feb 2010 13:56:38 -0500
> Here is one more big batch of wireless bits intended for 2.6.34. Along
> with the usual variety of driver fixes are some mac80211 bits from
> Johannes, a number of iwlwifi updates from Intel, and a big batch of of
> wl1271 bits from Nokia.
>
> Please let me know if there are problems!
Pulled, thanks a lot John.
There were two conflicts I had to resolve (some declarations in in
iwl-core.h and one of the rt* driver PCI ID tables).
Please double-check my work when I push this out to net-next-2.6
Thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next 3/6] cnic: Fix panic in cnic_iscsi_nl_msg_recv() when device is down.
From: Michael Chan @ 2010-02-26 7:01 UTC (permalink / raw)
To: 'Simon Horman'; +Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <20100226005114.GH3876@verge.net.au>
Simon Horman wrote:
> On Wed, Feb 24, 2010 at 04:42:06PM -0800, Michael Chan wrote:
> > Some data structures are freed when the device is down and it will
> > crash if an ISCSI netlink message is received. Add RCU protection
> > to prevent this. In the shutdown path, ulp_ops[CNIC_ULP_L4] is
> > assigned NULL and rcu_synchronized before freeing the data
> > structures.
>
> Is rcu_assign_pointer() unnecessary in cnic_cm_open()?
> It doesn't seem to be followed by rcu_synchronized() and the pointer
> doesn't seem to be accessible anywhere else at that time.
We assign a valid pointer in cnic_cm_open() so that it can be used
during run-time (in service_kcqes() for example). During shutdown in
cnic_stop_hw(), we assign NULL followed by rcu_synchronize().
^ permalink raw reply
* Re: [ethtool PATCH] ethtool: Support n-tuple filter programming
From: Peter P Waskiewicz Jr @ 2010-02-26 6:09 UTC (permalink / raw)
To: David Miller
Cc: jeff@garzik.org, Kirsher, Jeffrey T, netdev@vger.kernel.org,
gospo@redhat.com
In-Reply-To: <20100225.215357.140469725.davem@davemloft.net>
On Thu, 2010-02-25 at 21:53 -0800, David Miller wrote:
> From: Jeff Garzik <jeff@garzik.org>
> Date: Thu, 25 Feb 2010 21:26:38 -0500
>
> > On 02/25/2010 08:49 PM, Waskiewicz Jr, Peter P wrote:
> >> This will require a small kernel change. Will something like this be
> >> pulled in at this point, given that 2.6.33 just released?
> >
> > The n-tuple stuff is not in 2.6.33's ethtool interface, so it hasn't
> > actually made it into a released kernel at this point.
> >
> > It seems reasonable for 2.6.34 to either add ETHTOOL_GSTRINGS_COUNT or
> > update drvinfo. Even if net-next has already been pulled into
> > post-2.6.33 merge window, that would IMO qualify as a reasonable
> > interface bugfix to get upstream. The ethtool n-tuple ABI is not
> > locked into stone until 2.6.34 is released by Linus.
>
> Right.
Sounds good. I wanted to make sure before I changed the ethtool bits.
Expect a patch for both the kernel side and userspace side shortly.
-PJ
^ permalink raw reply
* Re: [patch] IPVS: ip_vs_lblcr: use list head
From: Patrick McHardy @ 2010-02-26 5:59 UTC (permalink / raw)
To: David Miller; +Cc: horms, netdev, lvs-devel, wensong, ja
In-Reply-To: <20100225.215540.94527171.davem@davemloft.net>
David Miller wrote:
> From: Simon Horman <horms@verge.net.au>
> Date: Fri, 26 Feb 2010 14:02:11 +1100
>
>> Use list_head rather than a custom list implementation.
>>
>> Signed-off-by: Simon Horman <horms@verge.net.au>
>
> Thanks for doing this, I'm sure Patrick will integrate this
> patch for you.
>
Will do, I'll send another pull request tonight.
^ permalink raw reply
* Re: [patch] IPVS: ip_vs_lblcr: use list head
From: David Miller @ 2010-02-26 5:55 UTC (permalink / raw)
To: horms; +Cc: netdev, lvs-devel, wensong, ja, kaber
In-Reply-To: <20100226030211.GB6111@verge.net.au>
From: Simon Horman <horms@verge.net.au>
Date: Fri, 26 Feb 2010 14:02:11 +1100
> Use list_head rather than a custom list implementation.
>
> Signed-off-by: Simon Horman <horms@verge.net.au>
Thanks for doing this, I'm sure Patrick will integrate this
patch for you.
^ permalink raw reply
* Re: [ethtool PATCH] ethtool: Support n-tuple filter programming
From: David Miller @ 2010-02-26 5:53 UTC (permalink / raw)
To: jeff; +Cc: peter.p.waskiewicz.jr, jeffrey.t.kirsher, netdev, gospo
In-Reply-To: <4B87315E.4080905@garzik.org>
From: Jeff Garzik <jeff@garzik.org>
Date: Thu, 25 Feb 2010 21:26:38 -0500
> On 02/25/2010 08:49 PM, Waskiewicz Jr, Peter P wrote:
>> This will require a small kernel change. Will something like this be
>> pulled in at this point, given that 2.6.33 just released?
>
> The n-tuple stuff is not in 2.6.33's ethtool interface, so it hasn't
> actually made it into a released kernel at this point.
>
> It seems reasonable for 2.6.34 to either add ETHTOOL_GSTRINGS_COUNT or
> update drvinfo. Even if net-next has already been pulled into
> post-2.6.33 merge window, that would IMO qualify as a reasonable
> interface bugfix to get upstream. The ethtool n-tuple ABI is not
> locked into stone until 2.6.34 is released by Linus.
Right.
^ permalink raw reply
* Re: [RFC PATCH] accounting for socket backlog
From: David Miller @ 2010-02-26 5:52 UTC (permalink / raw)
To: yi.zhu; +Cc: netdev, alex.shi
In-Reply-To: <1267152253.16986.1655.camel@debian>
From: Zhu Yi <yi.zhu@intel.com>
Date: Fri, 26 Feb 2010 10:44:13 +0800
> On Thu, 2010-02-25 at 16:31 +0800, David Miller wrote:
>> Right now we can queue up a lot and still get it to the application
>> if it is slow getting scheduled onto a cpu, but if you put this
>> limit here it could result in lots of drops.
>
> Or we can replace the sk->sk_rcvbuf limit with a backlog own limit. We
> can queue "a lot", but not endless. We have to have a limit anyway.
Simply using (2 * sk->sk_rcvbuf) might be sufficient enough.
^ permalink raw reply
* Re: [PATCH 0/7] tcp: bugs and cleanup for 2.6.33
From: David Miller @ 2010-02-26 5:33 UTC (permalink / raw)
To: william.allen.simpson; +Cc: torvalds, akpm, linux-kernel, netdev
In-Reply-To: <4B86DDCB.50608@gmail.com>
From: William Allen Simpson <william.allen.simpson@gmail.com>
Date: Thu, 25 Feb 2010 15:30:03 -0500
> I'd have thought that there would be greater interest about patching
> crashing bugs, signed versus unsigned (underflow) bugs, TCP DoS bugs,
> TCP data corruption, and TCP performance problems....
Your patches add as many bugs and problems as they claim to solve.
You also attack, in your commit messages and code coments, the
very people you want to look at your changes and integrate them.
How you hope to make forward progress in these circumstances is
beyond me.
Just remember William: Whilst people have a right to say whatever
they want, they must earn the privilege to being listened to.
And currently many people have you set strictly to ignore.
^ permalink raw reply
* RE: Gianfar driver failing on MPC8641D based board
From: Kumar Gopalpet-B05799 @ 2010-02-26 4:58 UTC (permalink / raw)
To: avorontsov, Paul Gortmaker
Cc: Martyn Welch, linuxppc-dev list, netdev, linux-kernel, davem,
Kumar Gala
In-Reply-To: <20100226031452.GA11319@oksana.dev.rtsoft.ru>
>-----Original Message-----
>From: Anton Vorontsov [mailto:avorontsov@ru.mvista.com]
>Sent: Friday, February 26, 2010 8:45 AM
>To: Paul Gortmaker
>Cc: Martyn Welch; linuxppc-dev list; netdev@vger.kernel.org;
>linux-kernel@vger.kernel.org; Kumar Gopalpet-B05799;
>davem@davemloft.net; Kumar Gala
>Subject: Re: Gianfar driver failing on MPC8641D based board
>
>On Thu, Feb 25, 2010 at 07:53:30PM -0500, Paul Gortmaker wrote:
>[...]
>> I was able to reproduce it on an 8641D and bisected it down to this:
>>
>> -----------
>> commit a3bc1f11e9b867a4f49505ecac486a33af248b2e
>> Author: Anton Vorontsov <avorontsov@ru.mvista.com>
>> Date: Tue Nov 10 14:11:10 2009 +0000
>>
>> gianfar: Revive SKB recycling
>
>Thanks for the bisect. I have a guess why tx hangs in SMP
>case. Could anyone try the patch down below?
>
>[...]
>> ...which probably explains why you weren't seeing it on non-SMP.
>> I'd imagine it would show up on any of the e500mc boards too.
>
>Yeah.. Pity, I don't have SMP boards anymore. I'll try to get
>one though.
>
>
>diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
>index 8bd3c9f..3ff3bd0 100644
>--- a/drivers/net/gianfar.c
>+++ b/drivers/net/gianfar.c
>@@ -2614,6 +2614,8 @@ static int gfar_poll(struct napi_struct
>*napi, int budget)
> tx_queue = priv->tx_queue[rx_queue->qindex];
>
> tx_cleaned += gfar_clean_tx_ring(tx_queue);
>+ if (!tx_cleaned && !tx_queue->num_txbdfree)
>+ tx_cleaned += 1; /* don't
>complete napi */
> rx_cleaned_per_queue =
>gfar_clean_rx_ring(rx_queue,
>
>budget_per_queue);
> rx_cleaned += rx_cleaned_per_queue;
>
Anton,
There is also one more issue that I have been observing with the patch
"gianfar: Revive SKB recycling".
The issue is when I do a IPV4 forwarding test scenario with
bidirectional flows (SMP environment). I am using Spirent smart bits
(smartflow) for automation testing and I frequently observe smart flow
reporting "Rx packet counte greater than Tx packet count. Duplicate
packets might have been received".
To just get over the issue I have removed this patch and I didn't see
the issue.
To a certain extent I could get over the problem by using atomic_t for
num_txbdfree (atomic_add and atomic_dec instructions for updating the
num_txbdfree) and completely removing the spin_locks in the tx routines.
Also, I feel we might want to make some more changes to the
gfar_clean_tx_ring( ) and gfar_start_xmit() routines so that they can
operate parallely.
I am really sorry for not posting it a bit earlier as I am caught up
with some urgent issues.
--
Thanks
Sandeep
^ permalink raw reply
* FREE LOTTO 2010 WINNER!!
From: Mr Sung Johnson @ 2010-02-26 2:39 UTC (permalink / raw)
YOU HAVE WON! CONTACT MR. WILCOX: williams_wilcox@sify.com
^ permalink raw reply
* FREE LOTTO 2010 WINNER!!
From: Mr Sung Johnson @ 2010-02-26 2:45 UTC (permalink / raw)
YOU HAVE WON! CONTACT MR. WILCOX: williams_wilcox@sify.com
^ permalink raw reply
* FREE LOTTO 2010 WINNER!!
From: Mr Sung Johnson @ 2010-02-26 2:43 UTC (permalink / raw)
YOU HAVE WON! CONTACT MR. WILCOX: williams_wilcox@sify.com
^ permalink raw reply
* FREE LOTTO 2010 WINNER!!
From: Mr Sung Johnson @ 2010-02-26 2:42 UTC (permalink / raw)
YOU HAVE WON! CONTACT MR. WILCOX: williams_wilcox@sify.com
^ permalink raw reply
* Visiting Nurses & RN's - 91,386 total records with 2,788 emails and 2,390 fax numbers
From: Ochoa I Homer @ 2010-02-26 3:47 UTC (permalink / raw)
To: shibbir, mba, reimbursement
For details, samples and counts on our US listings please
email me at my other email address Preston.Cotton@fjmlist.Co.CC
Forward email to rembox@fjmlist.Co.CC to purge you from our records
^ permalink raw reply
* ***SPAM*** [discount list source - all kinds of marketing lists for cheap]
From: Johns hex @ 2010-02-26 3:43 UTC (permalink / raw)
To: shayes, sholloway, rich, skinnera
For details, samples and counts on our US listings please
email me at my other email address Tommie.Kendall@fjmlist.Co.CC
to terminate please send a blank message to rembox@fjmlist.Co.CC
^ permalink raw reply
* Advice on RCU for IPVS
From: Simon Horman @ 2010-02-26 3:18 UTC (permalink / raw)
To: netdev, lvs-devel
Hi,
I have been looking at converting the rwlocks in IPVS over to use RCU.
A problem that I am facing is that the lblcr scheduler uses
a write lock on list A and then taking a write lock on list B.
Where list B is basically part of one of the elements of list A.
This problem is present in ip_vs_lblcr_schedule() and
the key code looks like this.
/* First look in our cache */
read_lock(&svc->sched_lock);
en = ip_vs_lblcr_get(svc->af, tbl, &iph.daddr);
if (en) {
...
/* Get the least loaded destination */
read_lock(&en->set.lock);
dest = ip_vs_dest_set_min(&en->set);
read_unlock(&en->set.lock);
...
write_lock(&en->set.lock);
m = ip_vs_dest_set_max(&en->set);
if (m)
ip_vs_dest_set_erase(&en->set, m);
write_unlock(&en->set.lock);
...
/* Update our cache entry */
write_lock(&en->set.lock);
ip_vs_dest_set_insert(&en->set, dest);
write_unlock(&en->set.lock);
}
read_unlock(&svc->sched_lock);
dest is referenced counted and doesn't seem to need to be guarded
by svc->sched_lock.
It seems to me that this is quite difficult to convert over to RCU
as there are write-side critical sections inside a read-side critical
section.
I investigated reference counting the return value of
ip_vs_lblcr_get() or the return value of ip_vs_dest_set_max() and
ip_vs_dest_set_insert(). But this seems to be difficult,
especially at rmmod time.
I also considered just making the whole thing a write-side critical section.
Which seems to be somewhat of a sledge-hammer and result in
a critical section that is much larger than I would like. Though
no bigger than the existing area covered by the read-lock on
svc->sched_lock.
Any suggestions would be appreciated.
^ permalink raw reply
* [RFC][PATCH] ns: Syscalls for better namespace sharing control. v2
From: Eric W. Biederman @ 2010-02-26 3:15 UTC (permalink / raw)
To: hadi
Cc: Daniel Lezcano, Patrick McHardy, Linux Netdev List, containers,
Netfilter Development Mailinglist, Ben Greear, Serge Hallyn,
Matt Helsley
In-Reply-To: <m1pr3t2fvl.fsf_-_@fess.ebiederm.org>
Introduce two new system calls:
int nsfd(pid_t pid, unsigned long nstype);
int setns(unsigned long nstype, int fd);
These two new system calls address three specific problems that can
make namespaces hard to work with.
- Namespaces require a dedicated process to pin them in memory.
- It is not possible to use a namespace unless you are the
child of the original creator.
- Namespaces don't have names that userspace can use to talk
about them.
The nsfd() system call returns a file descriptor that can
be used to talk about a specific namespace, and to keep
the specified namespace alive.
The file descriptor returned from nsfd has the lifetime
semantics of a deleted file. As long as the fd is
open or it is bind mounted into the filesystem
namespace the namespace will be kept alive.
The fd returned by nsfd() can be bind mounted as:
mount --bind /proc/self/fd/N /some/filesystem/path
open works on the fd returned by nsfd() so another
process can get a hold of it and do interesting things.
Overall that allows for naming of namespaces with
userspace policy.
setns() allows changing the namespace of the current process
to a namespace that originates with nsfd().
v2: The code is tested and works in the common case.
The vfs has some of the strangest rules...
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
Enough for one day. This code works, now it just needs
a some more use/testing and careful scrutiny before 2.6.35 rolls
around.
arch/x86/ia32/ia32entry.S | 2 +
arch/x86/include/asm/unistd_32.h | 4 +-
arch/x86/include/asm/unistd_64.h | 4 +
arch/x86/kernel/syscall_table_32.S | 2 +
fs/Makefile | 2 +-
fs/nsfd.c | 320 ++++++++++++++++++++++++++++++++++++
include/linux/magic.h | 1 +
include/linux/nsproxy.h | 1 +
include/linux/nstype.h | 6 +
kernel/nsproxy.c | 17 ++
10 files changed, 357 insertions(+), 2 deletions(-)
create mode 100644 fs/nsfd.c
create mode 100644 include/linux/nstype.h
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 53147ad..9fd33de 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -842,4 +842,6 @@ ia32_sys_call_table:
.quad compat_sys_rt_tgsigqueueinfo /* 335 */
.quad sys_perf_event_open
.quad compat_sys_recvmmsg
+ .quad sys_nsfd
+ .quad sys_setns
ia32_syscall_end:
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 3baf379..5b7833c 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -343,10 +343,12 @@
#define __NR_rt_tgsigqueueinfo 335
#define __NR_perf_event_open 336
#define __NR_recvmmsg 337
+#define __NR_nsfd 338
+#define __NR_setns 339
#ifdef __KERNEL__
-#define NR_syscalls 338
+#define NR_syscalls 340
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index 4843f7b..260d542 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -663,6 +663,10 @@ __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
#define __NR_recvmmsg 299
__SYSCALL(__NR_recvmmsg, sys_recvmmsg)
+#define __NR_nsfd 300
+__SYSCALL(__NR_nsfd, sys_nsfd)
+#define __NR_setns 301
+__SYSCALL(__NR_setns, sys_setns)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 15228b5..e09a45b 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -337,3 +337,5 @@ ENTRY(sys_call_table)
.long sys_rt_tgsigqueueinfo /* 335 */
.long sys_perf_event_open
.long sys_recvmmsg
+ .long sys_nsfd
+ .long sys_setns
diff --git a/fs/Makefile b/fs/Makefile
index af6d047..74d5091 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \
attr.o bad_inode.o file.o filesystems.o namespace.o \
seq_file.o xattr.o libfs.o fs-writeback.o \
pnode.o drop_caches.o splice.o sync.o utimes.o \
- stack.o fs_struct.o
+ stack.o fs_struct.o nsfd.o
ifeq ($(CONFIG_BLOCK),y)
obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o
diff --git a/fs/nsfd.c b/fs/nsfd.c
new file mode 100644
index 0000000..ec04a1e
--- /dev/null
+++ b/fs/nsfd.c
@@ -0,0 +1,320 @@
+#include <linux/nstype.h>
+#include <linux/fs.h>
+#include <linux/magic.h>
+#include <net/net_namespace.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/cred.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/nsproxy.h>
+#include <linux/kernel.h>
+#include <linux/syscalls.h>
+#include <linux/fs_struct.h>
+
+static struct vfsmount *nsfd_mnt __read_mostly;
+static struct inode *nsfd_inode;
+
+static const struct file_operations nsfd_file_operations = {
+ .llseek = no_llseek,
+};
+
+static const struct super_operations nsfd_super_operations = {
+ .statfs = simple_statfs,
+};
+
+static char *nsfd_dname(struct dentry *dentry, char *buffer, int buflen)
+{
+ static const char name[] = "nsfd";
+
+ if (sizeof(name) > buflen)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ return memcpy(buffer, name, sizeof(name));
+}
+
+static const struct dentry_operations nsfd_dentry_operations = {
+ .d_dname = nsfd_dname,
+};
+
+static struct inode *nsfd_mkinode(struct super_block *sb)
+{
+ struct inode *inode;
+
+ inode = new_inode(sb);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ inode->i_fop = &nsfd_file_operations;
+
+ /*
+ * Mark the inode dirty from the very beginning,
+ * that way it will never be moved to the dirty
+ * list because mark_inode_dirty() will think that
+ * it already _is_ on the dirty list.
+ */
+ inode->i_state = I_DIRTY;
+ inode->i_ino = 1;
+ inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ inode->i_flags = S_IMMUTABLE;
+
+ return inode;
+}
+
+static struct dentry *nsfd_alloc_dentry(struct inode *inode)
+{
+ struct dentry *dentry;
+
+ /*
+ * We know the nsfd_inode inode count is always greater than zero,
+ * so we can avoid doing an igrab() and we can use an open-coded
+ * atomic_inc().
+ */
+ dentry = d_alloc_root(inode);
+ if (dentry) {
+ atomic_inc(&inode->i_count);
+ dentry->d_op = &nsfd_dentry_operations;
+ }
+ return dentry;
+}
+
+static int nsfd_fill_super(struct super_block *sb, void *data, int silent)
+{
+ struct inode *inode = NULL;
+
+ sb->s_flags = 0;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_blocksize = PAGE_SIZE;
+ sb->s_blocksize_bits = PAGE_SHIFT;
+ sb->s_magic = NSFD_FS_MAGIC;
+ sb->s_op = &nsfd_super_operations;
+ sb->s_time_gran = 1;
+
+ inode = nsfd_mkinode(sb);
+ if (!inode)
+ goto Enomem;
+
+ sb->s_root = nsfd_alloc_dentry(inode);
+ if (!sb->s_root)
+ goto Enomem;
+
+ /* Save the inode for later.. */
+ nsfd_inode = inode;
+
+ return 0;
+
+Enomem:
+ iput(inode);
+ return -ENOMEM;
+}
+
+static int nsfd_get_sb(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data, struct vfsmount *mnt)
+{
+ /* We can't use get_sb_psuedo because that sets MS_NOUSER */
+ return get_sb_single(fs_type, 0, NULL, nsfd_fill_super, mnt);
+}
+
+
+static struct file_system_type nsfd_fs_type = {
+ .name = "nsfd",
+ .get_sb = nsfd_get_sb,
+ .kill_sb = kill_anon_super,
+
+};
+
+static void netns_dentry_release(struct dentry *dentry)
+{
+ put_net(dentry->d_fsdata);
+ dentry->d_fsdata = NULL;
+}
+
+static const struct dentry_operations netns_dentry_operations = {
+ .d_dname = nsfd_dname,
+ .d_release = netns_dentry_release,
+};
+
+static const struct dentry_operations *nsfd_dops[] = {
+ [NSTYPE_NET] = &netns_dentry_operations,
+};
+
+static const struct dentry_operations *nstype_dops(unsigned long nstype)
+{
+ const struct dentry_operations *d_op = NULL;
+
+ if (nstype < sizeof(nsfd_dops)/sizeof(nsfd_dops[0]))
+ d_op = nsfd_dops[nstype];
+
+ return d_op;
+}
+
+static struct file *nsfd_fget(int fd, unsigned long nstype)
+{
+ const struct dentry_operations *d_op;
+ struct file *file;
+
+ d_op = nstype_dops(nstype);
+ if (!d_op)
+ return ERR_PTR(-EINVAL);
+
+ file = fget(fd);
+ if (!file)
+ return ERR_PTR(-EBADF);
+
+ if (file->f_op != &nsfd_file_operations)
+ goto out_invalid;
+
+ if (file->f_path.dentry->d_op != d_op)
+ goto out_invalid;
+
+ return file;
+
+out_invalid:
+ fput(file);
+ return ERR_PTR(-EINVAL);
+}
+
+
+static struct file *nsfd_getfile(void)
+{
+ struct path path;
+ struct file *file;
+
+ path.dentry = nsfd_alloc_dentry(nsfd_inode);
+ if (!path.dentry)
+ return ERR_PTR(-ENOMEM);
+
+ /* HACK I need a vfsmnt with mnt_ns == current_nsproxy_mnt_ns
+ * and (mnt_sb->s_flags & MS_NOUSER) == 0. The only way I can
+ * get such a vfsmount without having an instnace of my filesystem
+ * mounted in the namespace is to steal one.
+ */
+ path.mnt = mntget(current->fs->root.mnt);
+
+ file = alloc_file(&path, FMODE_READ, &nsfd_file_operations);
+ if (!file) {
+ path_put(&path);
+ return ERR_PTR(-ENFILE);
+ }
+ file->f_mapping = nsfd_inode->i_mapping;
+
+ file->f_pos = 0;
+ file->f_flags = O_RDONLY;
+ file->f_version = 0;
+ file->private_data = NULL;
+
+ return file;
+}
+
+static void *nsfd_getns(pid_t pid, unsigned long nstype)
+{
+ struct task_struct *task;
+ struct nsproxy *nsproxy;
+ void *ns;
+
+ ns = ERR_PTR(-ESRCH);
+ rcu_read_lock();
+ if (pid == 0)
+ task = current;
+ else
+ task = find_task_by_vpid(pid);
+ if (!task)
+ goto out;
+
+ ns = ERR_PTR(-EPERM);
+ if (!ptrace_may_access(task, PTRACE_MODE_ATTACH))
+ goto out;
+
+ ns = ERR_PTR(-ESRCH);
+ nsproxy = task_nsproxy(task);
+ if (!nsproxy)
+ goto out;
+
+ ns = ERR_PTR(-EINVAL);
+ switch(nstype) {
+ case NSTYPE_NET:
+ ns = get_net(nsproxy->net_ns);
+ break;
+ }
+out:
+ rcu_read_unlock();
+ return ns;
+}
+
+SYSCALL_DEFINE2(nsfd, pid_t, pid, unsigned long, nstype)
+{
+ const struct dentry_operations *d_op;
+ struct file *file;
+ int fd;
+ void *ns;
+
+ d_op = nstype_dops(nstype);
+ if (!d_op)
+ return -EINVAL;
+
+ file = nsfd_getfile();
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ ns = nsfd_getns(pid, nstype);
+ if (IS_ERR(ns)) {
+ fput(file);
+ return PTR_ERR(ns);
+ }
+
+ file->f_dentry->d_fsdata = ns;
+ file->f_dentry->d_op = d_op;
+
+ fd = get_unused_fd();
+ if (fd < 0) {
+ fput(file);
+ return fd;
+ }
+ fd_install(fd, file);
+
+ return fd;
+}
+
+
+SYSCALL_DEFINE2(setns, unsigned long, nstype, int, fd)
+{
+ struct file *file;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ file = nsfd_fget(fd, nstype);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ set_namespace(nstype, file->f_dentry->d_fsdata);
+
+ fput(file);
+ return 0;
+}
+
+
+static int __init nsfd_init(void)
+{
+ int error;
+
+ error = register_filesystem(&nsfd_fs_type);
+ if (error)
+ goto err_exit;
+
+ nsfd_mnt = kern_mount(&nsfd_fs_type);
+ if (IS_ERR(nsfd_mnt)) {
+ error = PTR_ERR(nsfd_mnt);
+ goto err_unregister_filesystem;
+ }
+
+ return 0;
+
+err_unregister_filesystem:
+ unregister_filesystem(&nsfd_fs_type);
+err_exit:
+ panic(KERN_ERR "nsfd_init() failed (%d)\n", error);
+}
+
+fs_initcall(nsfd_init);
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 76285e0..a4fe6eb 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -26,6 +26,7 @@
#define ISOFS_SUPER_MAGIC 0x9660
#define JFFS2_SUPER_MAGIC 0x72b6
#define ANON_INODE_FS_MAGIC 0x09041934
+#define NSFD_FS_MAGIC 0x6e736664
#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 7b370c7..45f1e07 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -65,6 +65,7 @@ static inline struct nsproxy *task_nsproxy(struct task_struct *tsk)
int copy_namespaces(unsigned long flags, struct task_struct *tsk);
void exit_task_namespaces(struct task_struct *tsk);
void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
+void set_namespace(unsigned long nstype, void *ns);
void free_nsproxy(struct nsproxy *ns);
int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
struct fs_struct *);
diff --git a/include/linux/nstype.h b/include/linux/nstype.h
new file mode 100644
index 0000000..3bdf856
--- /dev/null
+++ b/include/linux/nstype.h
@@ -0,0 +1,6 @@
+#ifndef _LINUX_NSTYPE_H
+#define _LINUX_NSTYPE_H
+
+#define NSTYPE_NET 0
+
+#endif /* _LINUX_NSTYPE_H */
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 09b4ff9..574461c 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -21,6 +21,7 @@
#include <linux/pid_namespace.h>
#include <net/net_namespace.h>
#include <linux/ipc_namespace.h>
+#include <linux/nstype.h>
static struct kmem_cache *nsproxy_cachep;
@@ -221,6 +222,22 @@ void exit_task_namespaces(struct task_struct *p)
switch_task_namespaces(p, NULL);
}
+void set_namespace(unsigned long nstype, void *ns)
+{
+ struct task_struct *tsk = current;
+ struct nsproxy *new_nsproxy;
+
+ new_nsproxy = create_new_namespaces(0, tsk, tsk->fs);
+ switch(nstype) {
+ case NSTYPE_NET:
+ put_net(new_nsproxy->net_ns);
+ new_nsproxy->net_ns = get_net(ns);
+ break;
+ }
+
+ switch_task_namespaces(tsk, new_nsproxy);
+}
+
static int __init nsproxy_cache_init(void)
{
nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
--
1.6.5.2.143.g8cc62
^ permalink raw reply related
* Re: Gianfar driver failing on MPC8641D based board
From: Anton Vorontsov @ 2010-02-26 3:14 UTC (permalink / raw)
To: Paul Gortmaker
Cc: netdev, linux-kernel, Martyn Welch, linuxppc-dev list,
Sandeep Gopalpet, davem
In-Reply-To: <7d1d9c251002251653n6473f01ex2d43933ec6aa010b@mail.gmail.com>
On Thu, Feb 25, 2010 at 07:53:30PM -0500, Paul Gortmaker wrote:
[...]
> I was able to reproduce it on an 8641D and bisected it down to this:
>
> -----------
> commit a3bc1f11e9b867a4f49505ecac486a33af248b2e
> Author: Anton Vorontsov <avorontsov@ru.mvista.com>
> Date: Tue Nov 10 14:11:10 2009 +0000
>
> gianfar: Revive SKB recycling
Thanks for the bisect. I have a guess why tx hangs in
SMP case. Could anyone try the patch down below?
[...]
> ...which probably explains why you weren't seeing it on non-SMP.
> I'd imagine it would show up on any of the e500mc boards too.
Yeah.. Pity, I don't have SMP boards anymore. I'll try
to get one though.
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 8bd3c9f..3ff3bd0 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2614,6 +2614,8 @@ static int gfar_poll(struct napi_struct *napi, int budget)
tx_queue = priv->tx_queue[rx_queue->qindex];
tx_cleaned += gfar_clean_tx_ring(tx_queue);
+ if (!tx_cleaned && !tx_queue->num_txbdfree)
+ tx_cleaned += 1; /* don't complete napi */
rx_cleaned_per_queue = gfar_clean_rx_ring(rx_queue,
budget_per_queue);
rx_cleaned += rx_cleaned_per_queue;
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox