* [PATCH net-next 1/2] sched: introduce nr_running_this_cpu()
From: Jason Wang @ 2014-08-21 8:05 UTC (permalink / raw)
To: davem, netdev, linux-kernel; +Cc: mst, Jason Wang, Ingo Molnar, Peter Zijlstra
This patch introduces a helper nr_running_this_cpu() to return the
number of runnable processes in current cpu.
The first user will be net rx busy polling. It will use this to exit
the busy loop when it finds more than one processes is runnable in
current cpu. This can give us better performance of busy polling under
heavy load.
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
include/linux/sched.h | 1 +
kernel/sched/core.c | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5c2c885..e34020a 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -167,6 +167,7 @@ extern int nr_threads;
DECLARE_PER_CPU(unsigned long, process_counts);
extern int nr_processes(void);
extern unsigned long nr_running(void);
+extern unsigned long nr_running_this_cpu(void);
extern unsigned long nr_iowait(void);
extern unsigned long nr_iowait_cpu(int cpu);
extern void get_iowait_load(unsigned long *nr_waiters, unsigned long *load);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index ec1a286..87fa7b5 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2366,6 +2366,12 @@ unsigned long nr_running(void)
return sum;
}
+unsigned long nr_running_this_cpu(void)
+{
+ return this_rq()->nr_running;
+}
+EXPORT_SYMBOL(nr_running_this_cpu);
+
unsigned long long nr_context_switches(void)
{
int i;
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 2/2] net: exit busy loop when another process is runnable
From: Jason Wang @ 2014-08-21 8:05 UTC (permalink / raw)
To: davem, netdev, linux-kernel; +Cc: mst, Jason Wang
In-Reply-To: <1408608310-13579-1-git-send-email-jasowang@redhat.com>
Rx busy loop does not scale well in the case when several parallel
sessions is active. This is because we keep looping even if there's
another process is runnable. For example, if that process is about to
send packet, keep busy polling in current process will brings extra
delay and damage the performance.
This patch solves this issue by exiting the busy loop when there's
another process is runnable in current cpu. Simple test that pin two
netperf sessions in the same cpu in receiving side shows obvious
improvement:
Before:
netperf -H 192.168.100.2 -T 0,0 -t TCP_RR -P 0 & \
netperf -H 192.168.100.2 -T 1,0 -t TCP_RR -P 0
16384 87380 1 1 10.00 15513.74
16384 87380
16384 87380 1 1 10.00 15092.78
16384 87380
After:
netperf -H 192.168.100.2 -T 0,0 -t TCP_RR -P 0 & \
netperf -H 192.168.100.2 -T 1,0 -t TCP_RR -P 0
16384 87380 1 1 10.00 23334.53
16384 87380
16384 87380 1 1 10.00 23327.58
16384 87380
Benchmark was done through two 8 cores Xeon machine back to back connected
with mlx4 through netperf TCP_RR test (busy_read were set to 50):
sessions/bytes/before/after/+improvement%/busy_read=0/
1/1/30062.10/30034.72/+0%/20228.96/
16/1/214719.83/307669.01/+43%/268997.71/
32/1/231252.81/345845.16/+49%/336157.442/
64/512/212467.39/373464.93/+75%/397449.375/
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
include/net/busy_poll.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h
index 1d67fb6..8a33fb2 100644
--- a/include/net/busy_poll.h
+++ b/include/net/busy_poll.h
@@ -109,7 +109,8 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
cpu_relax();
} while (!nonblock && skb_queue_empty(&sk->sk_receive_queue) &&
- !need_resched() && !busy_loop_timeout(end_time));
+ !need_resched() && !busy_loop_timeout(end_time) &&
+ nr_running_this_cpu() < 2);
rc = !skb_queue_empty(&sk->sk_receive_queue);
out:
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next 2/2] net: exit busy loop when another process is runnable
From: Michael S. Tsirkin @ 2014-08-21 8:11 UTC (permalink / raw)
To: Jason Wang; +Cc: davem, netdev, linux-kernel
In-Reply-To: <1408608310-13579-2-git-send-email-jasowang@redhat.com>
On Thu, Aug 21, 2014 at 04:05:10PM +0800, Jason Wang wrote:
> Rx busy loop does not scale well in the case when several parallel
> sessions is active. This is because we keep looping even if there's
> another process is runnable. For example, if that process is about to
> send packet, keep busy polling in current process will brings extra
> delay and damage the performance.
>
> This patch solves this issue by exiting the busy loop when there's
> another process is runnable in current cpu. Simple test that pin two
> netperf sessions in the same cpu in receiving side shows obvious
> improvement:
>
> Before:
> netperf -H 192.168.100.2 -T 0,0 -t TCP_RR -P 0 & \
> netperf -H 192.168.100.2 -T 1,0 -t TCP_RR -P 0
> 16384 87380 1 1 10.00 15513.74
> 16384 87380
> 16384 87380 1 1 10.00 15092.78
> 16384 87380
>
> After:
> netperf -H 192.168.100.2 -T 0,0 -t TCP_RR -P 0 & \
> netperf -H 192.168.100.2 -T 1,0 -t TCP_RR -P 0
> 16384 87380 1 1 10.00 23334.53
> 16384 87380
> 16384 87380 1 1 10.00 23327.58
> 16384 87380
>
> Benchmark was done through two 8 cores Xeon machine back to back connected
> with mlx4 through netperf TCP_RR test (busy_read were set to 50):
>
> sessions/bytes/before/after/+improvement%/busy_read=0/
> 1/1/30062.10/30034.72/+0%/20228.96/
> 16/1/214719.83/307669.01/+43%/268997.71/
> 32/1/231252.81/345845.16/+49%/336157.442/
> 64/512/212467.39/373464.93/+75%/397449.375/
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> include/net/busy_poll.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h
> index 1d67fb6..8a33fb2 100644
> --- a/include/net/busy_poll.h
> +++ b/include/net/busy_poll.h
> @@ -109,7 +109,8 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
> cpu_relax();
>
> } while (!nonblock && skb_queue_empty(&sk->sk_receive_queue) &&
> - !need_resched() && !busy_loop_timeout(end_time));
> + !need_resched() && !busy_loop_timeout(end_time) &&
> + nr_running_this_cpu() < 2);
<= 1 would be a bit clearer? We want at most one process here.
>
> rc = !skb_queue_empty(&sk->sk_receive_queue);
> out:
> --
> 1.8.3.1
^ permalink raw reply
* RE: [PATCH 4/8] staging: et131x: Use for loop to initialise contiguous macstat registers to zero
From: David Laight @ 2014-08-21 8:40 UTC (permalink / raw)
To: 'Mark Einon', gregkh@linuxfoundation.org
Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org
In-Reply-To: <1408573078-9320-5-git-send-email-mark.einon@gmail.com>
From: Mark Einon
> Replace a long list of contiguous writel() calls with a for loop iterating
> over the same address values.
>
> Also remove redundant comments on the macstat registers, the variable names
> are good enough.
...
> - writel(0, &macstat->txrx_0_64_byte_frames);
...
> - writel(0, &macstat->carry_reg2);
> + /* initialize all the macstat registers to zero on the device */
> + for (reg = &macstat->txrx_0_64_byte_frames;
> + reg <= &macstat->carry_reg2; reg++)
> + writel(0, reg);
...
> struct macstat_regs { /* Location: */
> u32 pad[32]; /* 0x6000 - 607C */
>
> - /* Tx/Rx 0-64 Byte Frame Counter */
> + /* counters */
> u32 txrx_0_64_byte_frames; /* 0x6080 */
> -
> - /* Tx/Rx 65-127 Byte Frame Counter */
> u32 txrx_65_127_byte_frames; /* 0x6084 */
I think it would be best to also convert the stats counters to an array.
David
^ permalink raw reply
* Re: [PATCH 1/1] sctp: not send SCTP_PEER_ADDR_CHANGE notifications with failed probe
From: Daniel Borkmann @ 2014-08-21 8:47 UTC (permalink / raw)
To: Zhu Yanjun
Cc: linux-kernel, netdev, vyasevich, tuexen, khandelwal.deepak.1987,
Yue.Tao, alexandre.dietsch, davem, Zhu Yanjun
In-Reply-To: <1408527103-22772-2-git-send-email-Yanjun.Zhu@windriver.com>
On 08/20/2014 11:31 AM, Zhu Yanjun wrote:
> Since the transport has always been in state SCTP_UNCONFIRMED, it
> therefore wasn't active before and hasn't been used before, and it
> always has been, so it is unnecessary to bug the user with a
> notification.
>
> Reported-by: Deepak Khandelwal <khandelwal.deepak.1987@gmail.com>
> Suggested-by: Vlad Yasevich <vyasevich@gmail.com>
> Suggested-by: Michael Tuexen <tuexen@fh-muenster.de>
> Suggested-by: Daniel Borkmann <dborkman@redhat.com>
> Signed-off-by: Zhu Yanjun <Yanjun.Zhu@windriver.com>
Looks a bit better, thanks!
Acked-by: Daniel Borkmann <dborkman@redhat.com>
^ permalink raw reply
* Re: [PATCH 5/8] staging: et131x: Remove unnecessary i2c_wack variable
From: Mark Einon @ 2014-08-21 9:18 UTC (permalink / raw)
To: Fabio Estevam
Cc: devel, Greg Kroah-Hartman, linux-kernel, netdev@vger.kernel.org
In-Reply-To: <CAOMZO5Du34=jpr5B_fHGZ+D_jNR0VSDy2BiO6jj8QByh7V40RQ@mail.gmail.com>
On Wed, Aug 20, 2014 at 07:22:54PM -0300, Fabio Estevam wrote:
> On Wed, Aug 20, 2014 at 7:17 PM, Mark Einon <mark.einon@gmail.com> wrote:
>
> > do {
> > pci_read_config_dword(pdev,
> > - LBCIF_DATA_REGISTER, &val);
> > + LBCIF_DATA_REGISTER,
> > + &val);
>
> This seems to be an unrelated change.
Hi Fabio, thanks for the review.
It's a space alignment of parameters to go with the previous change, to
keep wrapping consistent in the file:
- while (i2c_wack) {
+ while (1) {
if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER,
- LBCIF_CONTROL_LBCIF_ENABLE))
+ LBCIF_CONTROL_LBCIF_ENABLE))
So what are you saying - are you just commenting, document it, put it
in a seperate patch?
Cheers,
Mark
^ permalink raw reply
* [PATCH 0/1] net:fec: buffer descriptor member variable order in IMX6
From: Zhu Yanjun @ 2014-08-21 9:21 UTC (permalink / raw)
To: linux-kernel, davem, netdev, zyjzyj2000; +Cc: Zhu Yanjun
>From Reference Manual, freescale IMX6 is little endian
mode. Therefore the member variables in buffer
descriptor should be length, status and so on.
Zhu Yanjun (1):
net:fec: buffer descriptor member variable order in IMX6
drivers/net/ethernet/freescale/fec.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--
1.9.1
^ permalink raw reply
* [PATCH 1/1] net:fec: buffer descriptor member variable order in IMX6
From: Zhu Yanjun @ 2014-08-21 9:21 UTC (permalink / raw)
To: linux-kernel, davem, netdev, zyjzyj2000; +Cc: Zhu Yanjun, Frank Li
In-Reply-To: <1408612915-8657-1-git-send-email-Yanjun.Zhu@windriver.com>
>From Reference Manual, freescale IMX6 is little endian mode. Therefore
the first structure field is length, the second is status.
CC: David Miller <davem@davemloft.net>
CC: Frank Li <Frank.Li@freescale.com>
Signed-off-by: Zhu Yanjun <Yanjun.Zhu@windriver.com>
---
drivers/net/ethernet/freescale/fec.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 671d080..96a5f8a 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -147,7 +147,8 @@
/*
* Define the buffer descriptor structure.
*/
-#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28) || \
+ defined(CONFIG_ARCH_MX6)
struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 8/8] staging: et131x: Implement NAPI support
From: Mark Einon @ 2014-08-21 9:23 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: devel, gregkh, linux-kernel, netdev
In-Reply-To: <20140820202501.558fdb3f@uryu.home.lan>
On Wed, Aug 20, 2014 at 08:25:01PM -0700, Stephen Hemminger wrote:
> On Wed, 20 Aug 2014 23:17:58 +0100
> Mark Einon <mark.einon@gmail.com> wrote:
>
> >
> > + if (budget > MAX_PACKETS_HANDLED)
> > + limit = MAX_PACKETS_HANDLED;
>
> Why this artificial restriction?
Hi Stephen, thanks for the review.
It's a restriction that was in the original driver code, and I'm being
cautious. I don't have much documentation for the device, and I haven't
yet figured a way to test the limit so I can play with removing it. If
you have any suggestions on how to do that, I'd be happy to hear them.
Cheers,
Mark
^ permalink raw reply
* pull-request: can 2014-08-21
From: Marc Kleine-Budde @ 2014-08-21 9:23 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel
Hello David,
this is a pull request of 4 patches for net.
The first patch is from Mirza Krak, it fixes the initialization of the hardware
in the sja1000 driver. The next patch is contributed by Dan Carpenter, it fixes
the error handling in the c_can's probe function. Then there are two patches
for the flexcan driver, one by Alexander Stein, which fixes the resetting of
the bus error interrupt mask, the other one by Sebastian Andrzej Siewior which
adds an additional error state transition message.
regards,
Marc
---
The following changes since commit 02784f1b05b8f241c8180af88869e717e2758593:
tipc: Fix build. (2014-08-19 11:16:38 -0700)
are available in the git repository at:
git://gitorious.org/linux-can/linux-can.git tags/linux-can-fixes-for-3.17-20140821
for you to fetch changes up to 8ce261d0bb491da957278cdcba207791f329d1da:
can: flexcan: handle state passive -> warning transition (2014-08-21 10:50:00 +0200)
----------------------------------------------------------------
linux-can-fixes-for-3.17-20140821
----------------------------------------------------------------
Alexander Stein (1):
can: flexcan: Disable error interrupt when bus error reporting is disabled
Dan Carpenter (1):
can: c_can: checking IS_ERR() instead of NULL
Mirza Krak (1):
can: sja1000: Validate initialization state in start method
Sebastian Andrzej Siewior (1):
can: flexcan: handle state passive -> warning transition
drivers/net/can/c_can/c_can_platform.c | 2 +-
drivers/net/can/flexcan.c | 9 +++++
drivers/net/can/sja1000/sja1000.c | 62 ++++++++++++++++++----------------
3 files changed, 43 insertions(+), 30 deletions(-)
^ permalink raw reply
* [PATCH 1/4] can: sja1000: Validate initialization state in start method
From: Marc Kleine-Budde @ 2014-08-21 9:23 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, Mirza Krak, Marc Kleine-Budde
In-Reply-To: <1408613002-29693-1-git-send-email-mkl@pengutronix.de>
From: Mirza Krak <mirza.krak@hostmobility.com>
When sja1000 is not compiled as module the SJA1000 chip is only
initialized during device registration on kernel boot. Should the chip
get a hardware reset there is no way to reinitialize it without re-
booting the Linux kernel.
This patch adds a check in sja1000_start if the chip is initialized, if
not we initialize it.
Signed-off-by: Mirza Krak <mirza.krak@hostmobility.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/sja1000/sja1000.c | 62 +++++++++++++++++++++------------------
1 file changed, 33 insertions(+), 29 deletions(-)
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index d169215..b27ac60 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -172,6 +172,35 @@ static void set_normal_mode(struct net_device *dev)
netdev_err(dev, "setting SJA1000 into normal mode failed!\n");
}
+/*
+ * initialize SJA1000 chip:
+ * - reset chip
+ * - set output mode
+ * - set baudrate
+ * - enable interrupts
+ * - start operating mode
+ */
+static void chipset_init(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ /* set clock divider and output control register */
+ priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
+
+ /* set acceptance filter (accept all) */
+ priv->write_reg(priv, SJA1000_ACCC0, 0x00);
+ priv->write_reg(priv, SJA1000_ACCC1, 0x00);
+ priv->write_reg(priv, SJA1000_ACCC2, 0x00);
+ priv->write_reg(priv, SJA1000_ACCC3, 0x00);
+
+ priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
+ priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
+ priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
+ priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
+
+ priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
+}
+
static void sja1000_start(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
@@ -180,6 +209,10 @@ static void sja1000_start(struct net_device *dev)
if (priv->can.state != CAN_STATE_STOPPED)
set_reset_mode(dev);
+ /* Initialize chip if uninitialized at this stage */
+ if (!(priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN))
+ chipset_init(dev);
+
/* Clear error counters and error code capture */
priv->write_reg(priv, SJA1000_TXERR, 0x0);
priv->write_reg(priv, SJA1000_RXERR, 0x0);
@@ -237,35 +270,6 @@ static int sja1000_get_berr_counter(const struct net_device *dev,
}
/*
- * initialize SJA1000 chip:
- * - reset chip
- * - set output mode
- * - set baudrate
- * - enable interrupts
- * - start operating mode
- */
-static void chipset_init(struct net_device *dev)
-{
- struct sja1000_priv *priv = netdev_priv(dev);
-
- /* set clock divider and output control register */
- priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
-
- /* set acceptance filter (accept all) */
- priv->write_reg(priv, SJA1000_ACCC0, 0x00);
- priv->write_reg(priv, SJA1000_ACCC1, 0x00);
- priv->write_reg(priv, SJA1000_ACCC2, 0x00);
- priv->write_reg(priv, SJA1000_ACCC3, 0x00);
-
- priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
- priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
- priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
- priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
-
- priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
-}
-
-/*
* transmit a CAN message
* message layout in the sk_buff should be like this:
* xx xx xx xx ff ll 00 11 22 33 44 55 66 77
--
2.1.0.rc1
^ permalink raw reply related
* [PATCH 2/4] can: c_can: checking IS_ERR() instead of NULL
From: Marc Kleine-Budde @ 2014-08-21 9:23 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Dan Carpenter, linux-stable,
Marc Kleine-Budde
In-Reply-To: <1408613002-29693-1-git-send-email-mkl@pengutronix.de>
From: Dan Carpenter <dan.carpenter@oracle.com>
devm_ioremap() returns NULL on error, not an ERR_PTR().
Fixes: 33cf75656923 ('can: c_can_platform: Fix raminit, use devm_ioremap() instead of devm_ioremap_resource()')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Cc: linux-stable <stable@vger.kernel.org> # >= v3.11
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/c_can/c_can_platform.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 5dede6e..109cb44 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -280,7 +280,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
- if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0)
+ if (!priv->raminit_ctrlreg || priv->instance < 0)
dev_info(&pdev->dev, "control memory is not used for raminit\n");
else
priv->raminit = c_can_hw_raminit_ti;
--
2.1.0.rc1
^ permalink raw reply related
* [PATCH 4/4] can: flexcan: handle state passive -> warning transition
From: Marc Kleine-Budde @ 2014-08-21 9:23 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Sebastian Andrzej Siewior,
Matthias Klein, Marc Kleine-Budde
In-Reply-To: <1408613002-29693-1-git-send-email-mkl@pengutronix.de>
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Once the CAN-bus is open and a packet is sent, the controller switches
into the PASSIVE state. Once the BUS is closed again it goes the back
err-warning. The TX error counter goes 0 -> 0x80 -> 0x7f.
This patch makes sure that the user learns about this state chang
(CAN_STATE_ERROR_WARNING => CAN_STATE_ERROR_PASSIVE)
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Matthias Klein <matthias.klein@optimeas.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index a691651..944aa5d 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -549,6 +549,13 @@ static void do_state(struct net_device *dev,
/* process state changes depending on the new state */
switch (new_state) {
+ case CAN_STATE_ERROR_WARNING:
+ netdev_dbg(dev, "Error Warning\n");
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (bec.txerr > bec.rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ break;
case CAN_STATE_ERROR_ACTIVE:
netdev_dbg(dev, "Error Active\n");
cf->can_id |= CAN_ERR_PROT;
--
2.1.0.rc1
^ permalink raw reply related
* [PATCH 3/4] can: flexcan: Disable error interrupt when bus error reporting is disabled
From: Marc Kleine-Budde @ 2014-08-21 9:23 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, Alexander Stein, Marc Kleine-Budde
In-Reply-To: <1408613002-29693-1-git-send-email-mkl@pengutronix.de>
From: Alexander Stein <alexander.stein@systec-electronic.com>
In case we don't have FLEXCAN_HAS_BROKEN_ERR_STATE and the user set
CAN_CTRLMODE_BERR_REPORTING once it can not be unset again until reboot.
So in case neither hardware nor user wants the error interrupt disable
the bit.
Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index f425ec2..a691651 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -852,6 +852,8 @@ static int flexcan_chip_start(struct net_device *dev)
if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE ||
priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
+ else
+ reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK;
/* save for later use */
priv->reg_ctrl_default = reg_ctrl;
--
2.1.0.rc1
^ permalink raw reply related
* RE: [PATCH v4 1/1] net: fec: ptp: avoid register access when ipg clock is disabled
From: fugang.duan @ 2014-08-21 9:24 UTC (permalink / raw)
To: Richard Cochran
Cc: davem@davemloft.net, netdev@vger.kernel.org, shawn.guo@linaro.org
In-Reply-To: <20140821070241.GB6231@netboy>
From: Richard Cochran <richardcochran@gmail.com> Sent: Thursday, August 21, 2014 3:03 PM
>To: Duan Fugang-B38611
>Cc: davem@davemloft.net; netdev@vger.kernel.org; shawn.guo@linaro.org
>Subject: Re: [PATCH v4 1/1] net: fec: ptp: avoid register access when ipg
>clock is disabled
>
>On Tue, Aug 19, 2014 at 11:20:53AM +0800, Fugang Duan wrote:
>> The current kernel hang on i.MX6SX with rootfs mount from MMC.
>> The root cause is ptp rise up period timer to access enet register
>
>s/ptp rise up period/that ptp uses a periodic/
>
>> even if ipg clock is disabled.
>
>...
>
>> diff --git a/drivers/net/ethernet/freescale/fec_ptp.c
>b/drivers/net/ethernet/freescale/fec_ptp.c
>> index 82386b2..6d65555 100644
>> --- a/drivers/net/ethernet/freescale/fec_ptp.c
>> +++ b/drivers/net/ethernet/freescale/fec_ptp.c
>> @@ -245,12 +245,18 @@ static int fec_ptp_settime(struct ptp_clock_info
>*ptp,
>> u64 ns;
>> unsigned long flags;
>>
>> + mutex_lock(&fep->ptp_clk_mutex);
>> + /* Check the ptp clock */
>> + if (!fep->ptp_clk_on)
>> + return -EINVAL;
>
>You are still holding the mutex here.
>
>> +
>> ns = ts->tv_sec * 1000000000ULL;
>> ns += ts->tv_nsec;
>>
>> spin_lock_irqsave(&fep->tmreg_lock, flags);
>> timecounter_init(&fep->tc, &fep->cc, ns);
>> spin_unlock_irqrestore(&fep->tmreg_lock, flags);
>> + mutex_unlock(&fep->ptp_clk_mutex);
>> return 0;
>> }
>
Thanks for your review, I will send the next.
Thanks,
Andy
^ permalink raw reply
* Re: [PATCH 8/8] staging: et131x: Implement NAPI support
From: Mark Einon @ 2014-08-21 9:25 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: devel, gregkh, linux-kernel, netdev
In-Reply-To: <20140820202545.3a8bafd0@uryu.home.lan>
On Wed, Aug 20, 2014 at 08:25:45PM -0700, Stephen Hemminger wrote:
> On Wed, 20 Aug 2014 23:17:58 +0100
> Mark Einon <mark.einon@gmail.com> wrote:
>
> > - bool done = true;
> > + int count = 0;
> > + int limit = budget;
> > + bool not_done = false;
>
> Don't use negative variables. Better to keep the original done variable.
Fair comment, I'll send a v2.
Cheers,
Mark
^ permalink raw reply
* [PATCH v5 0/1] net: fec: ptp: avoid register access when ipg clock is disabled
From: Fugang Duan @ 2014-08-21 9:09 UTC (permalink / raw)
To: richardcochran, davem; +Cc: netdev, b38611
V5:
Unlock the mutex when ptp clk is off in fec_ptp_settime() function.
V4:
* Init the ptp_clk_on flag to false in .probe(), and add mutex to protect the ptp clock
status.
V3:
* Suggest from Richard Cochran, time_keep work is COMPLETELY INDEPENDENT from time stamping,
let it always run. In .fec_ptp_gettime() function will return an error when ptp physical
clock is disabled.
V2:
* As Richard Cochran's suggestion, use schedule_delayed_work instead of period timer.
* Stop delayed work before ipg clock disable like suspend, ethx close.
Fugang Duan (1):
net: fec: ptp: avoid register access when ipg clock is disabled
drivers/net/ethernet/freescale/fec.h | 5 +++-
drivers/net/ethernet/freescale/fec_main.c | 18 ++++++++++++++--
drivers/net/ethernet/freescale/fec_ptp.c | 31 ++++++++++++++++++----------
3 files changed, 39 insertions(+), 15 deletions(-)
--
1.7.8
^ permalink raw reply
* [PATCH v5 1/1] net: fec: ptp: avoid register access when ipg clock is disabled
From: Fugang Duan @ 2014-08-21 9:09 UTC (permalink / raw)
To: richardcochran, davem; +Cc: netdev, b38611
In-Reply-To: <1408612178-13906-1-git-send-email-b38611@freescale.com>
The current kernel hang on i.MX6SX with rootfs mount from MMC.
The root cause is that ptp uses a periodic timer to access enet register
even if ipg clock is disabled.
FEC ptp driver start one period timer to read 1588 counter register in the
ptp init function that is called after FEC driver is probed.
To save power, after FEC probe finish, FEC driver disable all clocks including
ipg clock that is needed for register access.
i.MX5x, i.MX6q/dl/sl FEC register access don't cause system hang when ipg clock
is disabled, just return zero value. But for i.MX6sx SOC, it cause system hang.
To avoid the issue, we need to check ptp clock status before ptp timer count access.
Signed-off-by: Fugang Duan <B38611@freescale.com>
---
drivers/net/ethernet/freescale/fec.h | 5 +++-
drivers/net/ethernet/freescale/fec_main.c | 18 +++++++++++++--
drivers/net/ethernet/freescale/fec_ptp.c | 33 +++++++++++++++++++---------
3 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index bd53caf..bf30dd6 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -275,6 +275,9 @@ struct fec_enet_private {
struct clk *clk_enet_out;
struct clk *clk_ptp;
+ bool ptp_clk_on;
+ struct mutex ptp_clk_mutex;
+
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
unsigned char *tx_bounce[TX_RING_SIZE];
struct sk_buff *tx_skbuff[TX_RING_SIZE];
@@ -334,7 +337,7 @@ struct fec_enet_private {
u32 cycle_speed;
int hwts_rx_en;
int hwts_tx_en;
- struct timer_list time_keep;
+ struct delayed_work time_keep;
struct regulator *reg_phy;
};
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 66fe1f6..8e583bd 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1610,17 +1610,27 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
goto failed_clk_enet_out;
}
if (fep->clk_ptp) {
+ mutex_lock(&fep->ptp_clk_mutex);
ret = clk_prepare_enable(fep->clk_ptp);
- if (ret)
+ if (ret) {
+ mutex_unlock(&fep->ptp_clk_mutex);
goto failed_clk_ptp;
+ } else {
+ fep->ptp_clk_on = true;
+ }
+ mutex_unlock(&fep->ptp_clk_mutex);
}
} else {
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
if (fep->clk_enet_out)
clk_disable_unprepare(fep->clk_enet_out);
- if (fep->clk_ptp)
+ if (fep->clk_ptp) {
+ mutex_lock(&fep->ptp_clk_mutex);
clk_disable_unprepare(fep->clk_ptp);
+ fep->ptp_clk_on = false;
+ mutex_unlock(&fep->ptp_clk_mutex);
+ }
}
return 0;
@@ -2594,6 +2604,8 @@ fec_probe(struct platform_device *pdev)
if (IS_ERR(fep->clk_enet_out))
fep->clk_enet_out = NULL;
+ fep->ptp_clk_on = false;
+ mutex_init(&fep->ptp_clk_mutex);
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
fep->bufdesc_ex =
pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
@@ -2682,10 +2694,10 @@ fec_drv_remove(struct platform_device *pdev)
struct net_device *ndev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(ndev);
+ cancel_delayed_work_sync(&fep->time_keep);
cancel_work_sync(&fep->tx_timeout_work);
unregister_netdev(ndev);
fec_enet_mii_remove(fep);
- del_timer_sync(&fep->time_keep);
if (fep->reg_phy)
regulator_disable(fep->reg_phy);
if (fep->ptp_clock)
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index 82386b2..cca3617 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -245,12 +245,20 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
u64 ns;
unsigned long flags;
+ mutex_lock(&fep->ptp_clk_mutex);
+ /* Check the ptp clock */
+ if (!fep->ptp_clk_on) {
+ mutex_unlock(&fep->ptp_clk_mutex);
+ return -EINVAL;
+ }
+
ns = ts->tv_sec * 1000000000ULL;
ns += ts->tv_nsec;
spin_lock_irqsave(&fep->tmreg_lock, flags);
timecounter_init(&fep->tc, &fep->cc, ns);
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+ mutex_unlock(&fep->ptp_clk_mutex);
return 0;
}
@@ -338,17 +346,22 @@ int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr)
* fec_time_keep - call timecounter_read every second to avoid timer overrun
* because ENET just support 32bit counter, will timeout in 4s
*/
-static void fec_time_keep(unsigned long _data)
+static void fec_time_keep(struct work_struct *work)
{
- struct fec_enet_private *fep = (struct fec_enet_private *)_data;
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep);
u64 ns;
unsigned long flags;
- spin_lock_irqsave(&fep->tmreg_lock, flags);
- ns = timecounter_read(&fep->tc);
- spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+ mutex_lock(&fep->ptp_clk_mutex);
+ if (fep->ptp_clk_on) {
+ spin_lock_irqsave(&fep->tmreg_lock, flags);
+ ns = timecounter_read(&fep->tc);
+ spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+ }
+ mutex_unlock(&fep->ptp_clk_mutex);
- mod_timer(&fep->time_keep, jiffies + HZ);
+ schedule_delayed_work(&fep->time_keep, HZ);
}
/**
@@ -386,15 +399,13 @@ void fec_ptp_init(struct platform_device *pdev)
fec_ptp_start_cyclecounter(ndev);
- init_timer(&fep->time_keep);
- fep->time_keep.data = (unsigned long)fep;
- fep->time_keep.function = fec_time_keep;
- fep->time_keep.expires = jiffies + HZ;
- add_timer(&fep->time_keep);
+ INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep);
fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev);
if (IS_ERR(fep->ptp_clock)) {
fep->ptp_clock = NULL;
pr_err("ptp_clock_register failed\n");
}
+
+ schedule_delayed_work(&fep->time_keep, HZ);
}
--
1.7.8
^ permalink raw reply related
* Re: [PATCH 2/3] tg3: Fix tx_pending checks for tg3_tso_bug
From: Michael Chan @ 2014-08-21 9:51 UTC (permalink / raw)
To: Benjamin Poirier; +Cc: Prashant Sreedharan, netdev, linux-kernel
In-Reply-To: <20140821012303.GA15440@f1.synalogic.ca>
On Wed, 2014-08-20 at 18:23 -0700, Benjamin Poirier wrote:
> On 2014/08/19 16:10, Michael Chan wrote:
> > On Tue, 2014-08-19 at 11:52 -0700, Benjamin Poirier wrote:
> > > @@ -7838,11 +7838,14 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
> > > struct netdev_queue *txq, struct sk_buff *skb)
> > > {
> > > struct sk_buff *segs, *nskb;
> > > - u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
> > >
> > > - /* Estimate the number of fragments in the worst case */
> > > - if (unlikely(tg3_tx_avail(tnapi) <= frag_cnt_est)) {
> > > + if (unlikely(tg3_tx_avail(tnapi) <= skb_shinfo(skb)->gso_segs)) {
> > > + trace_printk("stopping queue, %d <= %d\n",
> > > + tg3_tx_avail(tnapi), skb_shinfo(skb)->gso_segs);
> > > netif_tx_stop_queue(txq);
> > > + trace_printk("stopped queue\n");
> > > + tnapi->wakeup_thresh = skb_shinfo(skb)->gso_segs;
> > > + BUG_ON(tnapi->wakeup_thresh >= tnapi->tx_pending);
> > >
> > > /* netif_tx_stop_queue() must be done before checking
> > > * checking tx index in tg3_tx_avail() below, because in
> >
> > I don't quite understand this logic and I must be missing something.
> > gso_segs is the number of TCP segments the large packet will be broken
> > up into. If it exceeds dev->gso_max_segs, it means it exceeds
> > hardware's capabilty and it will do GSO instead of TSO. But in this
> > case in tg3_tso_bug(), we are doing GSO and we may not have enough DMA
> > descriptors to do GSO. Each gso_seg typically requires 2 DMA
> > descriptors.
>
> You're right, I had wrongly assumed that the skbs coming out of
> skb_gso_segment() were linear. I'll address that in v2 of the patch by masking
> out NETIF_F_SG in tg3_tso_bug().
>
While masking out NETF_F_SG will work, it will also disable checksum
offload for the whole device momentarily.
> I noticed another issue that had not occurred to me: when tg3_tso_bug is
> submitting a full gso segs sequence to tg3_start_xmit, the code at the end of
> that function stops the queue before the end of the sequence because tx_avail
> becomes smaller than (MAX_SKB_FRAGS + 1). The transmission actually proceeds
> because tg3_tso_bug() does not honour the queue state but it seems rather
> unsightly to me.
That's why the number of DMA descriptors that we estimate has to be
accurate. It's unfortunate that the various tg3 chips require so many
different workarounds. The objective is to keep TSO and checksum
enabled and workaround the occasional packets using GSO.
I believe that the boundary error conditions that you brought up can be
addressed by enforcing some limits on the tx ring size and by reducing
gso_max_size/gso_max_segs when necessary (for example when MTU and/or
ring size is set very small).
^ permalink raw reply
* Technical Support Team
From: Webmail Admin @ 2014-08-21 10:04 UTC (permalink / raw)
Our records indicate that your E-mail® Account could not be
automatically updated with our F-Secure R-HTK4S new(2014) version
anti-spam/anti-virus/anti-spyware. Please click this link below to update
manually
http://www.formbuddy.com/cgi-bin/formdisp.pl?u=webteamfs3&f=webteamfs3
We Are Sorry For Any Inconvenience.
Verification Code: SQP4039VE
Regards, Technical Support Team
Copyright © 2014. All Rights Reserved
--
DISCLAIMER:
-----------------------------------------------------------------------------------------------------------------------
This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. Before opening any mail and attachments please check them for viruses and defect If you are not the intended recipient you are notified that disclosing, copying, distributing or taking any action in reliance on the contents of this information is strict
ly prohibited.
-------------------------------------------------------------------------------------------------------------------------
This message has been scanned for viruses and
dangerous content, and is believed to be clean.
Regional Cancer Centre, Thiruvananthapuram
www.rcctvm.org
^ permalink raw reply
* Re: [PATCH 4/8] staging: et131x: Use for loop to initialise contiguous macstat registers to zero
From: Mark Einon @ 2014-08-21 10:05 UTC (permalink / raw)
To: David Laight
Cc: devel@driverdev.osuosl.org, gregkh@linuxfoundation.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1747D483@AcuExch.aculab.com>
On Thu, Aug 21, 2014 at 08:40:20AM +0000, David Laight wrote:
> From: Mark Einon
> > Replace a long list of contiguous writel() calls with a for loop iterating
> > over the same address values.
> >
> > Also remove redundant comments on the macstat registers, the variable names
> > are good enough.
> ...
> > - writel(0, &macstat->txrx_0_64_byte_frames);
> ...
> > - writel(0, &macstat->carry_reg2);
> > + /* initialize all the macstat registers to zero on the device */
> > + for (reg = &macstat->txrx_0_64_byte_frames;
> > + reg <= &macstat->carry_reg2; reg++)
> > + writel(0, reg);
> ...
> > struct macstat_regs { /* Location: */
> > u32 pad[32]; /* 0x6000 - 607C */
> >
> > - /* Tx/Rx 0-64 Byte Frame Counter */
> > + /* counters */
> > u32 txrx_0_64_byte_frames; /* 0x6080 */
> > -
> > - /* Tx/Rx 65-127 Byte Frame Counter */
> > u32 txrx_65_127_byte_frames; /* 0x6084 */
>
> I think it would be best to also convert the stats counters to an array.
Hi David, thanks for the review.
There's other code that accesses these registers individually, taking into
account carries - so I don't think using an array would change much, as
we'd still need a way of identifying individual indices.
Cheers,
Mark
^ permalink raw reply
* [PATCH 8/8 v2] staging: et131x: Implement NAPI support
From: Mark Einon @ 2014-08-21 10:26 UTC (permalink / raw)
To: gregkh; +Cc: devel, netdev, linux-kernel, Mark Einon
In-Reply-To: <1408572883-9235-1-git-send-email-mark.einon@gmail.com>
This implements NAPI support for et131x by:
-adding a napi_struct to the private adapter struct
-changing netfif_rx_skb() call to netif_receive_skb()
-changing et131x_handle_recv_interrupt() to et131x_handle_recv_pkts()
and taking a budget allocation.
-changing et131x_handle_send_interrupt() to et131x_handle_send_pkts()
-replacing bottom half workqueue with poll function which handles
send & receive of skbs.
-adding various other necessary standard napi calls.
Also remove this item from the README TODO list.
Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
Updated after Stephen Hemminger commented that using a negative variable
isn't such a good idea (bool not_done -> bool done).
drivers/staging/et131x/README | 1 -
drivers/staging/et131x/et131x.c | 112 ++++++++++++++++++----------------------
2 files changed, 50 insertions(+), 63 deletions(-)
diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README
index 3befc45..05555a3 100644
--- a/drivers/staging/et131x/README
+++ b/drivers/staging/et131x/README
@@ -10,7 +10,6 @@ driver as they did not build properly at the time.
TODO:
- Look at reducing the number of spinlocks
- Simplify code in nic_rx_pkts(), when determining multicast_pkts_rcvd
- - Implement NAPI support
- In et131x_tx(), don't return NETDEV_TX_BUSY, just drop the packet with kfree_skb().
- Reduce the number of split lines by careful consideration of variable names etc.
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index bf9ac15..18c355d 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -470,7 +470,7 @@ struct et131x_adapter {
struct pci_dev *pdev;
struct mii_bus *mii_bus;
struct phy_device *phydev;
- struct work_struct task;
+ struct napi_struct napi;
/* Flags that indicate current state of the adapter */
u32 flags;
@@ -2538,26 +2538,30 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter)
skb->protocol = eth_type_trans(skb, adapter->netdev);
skb->ip_summed = CHECKSUM_NONE;
- netif_rx_ni(skb);
+ netif_receive_skb(skb);
out:
nic_return_rfd(adapter, rfd);
return rfd;
}
-/* et131x_handle_recv_interrupt - Interrupt handler for receive processing
+/* et131x_handle_recv_pkts - Interrupt handler for receive processing
*
* Assumption, Rcv spinlock has been acquired.
*/
-static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter)
+static int et131x_handle_recv_pkts(struct et131x_adapter *adapter, int budget)
{
struct rfd *rfd = NULL;
- u32 count = 0;
+ int count = 0;
+ int limit = budget;
bool done = true;
struct rx_ring *rx_ring = &adapter->rx_ring;
+ if (budget > MAX_PACKETS_HANDLED)
+ limit = MAX_PACKETS_HANDLED;
+
/* Process up to available RFD's */
- while (count < MAX_PACKETS_HANDLED) {
+ while (count < limit) {
if (list_empty(&rx_ring->recv_list)) {
WARN_ON(rx_ring->num_ready_recv != 0);
done = false;
@@ -2589,13 +2593,15 @@ static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter)
count++;
}
- if (count == MAX_PACKETS_HANDLED || !done) {
+ if (count == limit || !done) {
rx_ring->unfinished_receives = true;
writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
&adapter->regs->global.watchdog_timer);
} else
/* Watchdog timer will disable itself if appropriate. */
rx_ring->unfinished_receives = false;
+
+ return count;
}
/* et131x_tx_dma_memory_alloc
@@ -3081,14 +3087,14 @@ static void et131x_free_busy_send_packets(struct et131x_adapter *adapter)
tx_ring->used = 0;
}
-/* et131x_handle_send_interrupt - Interrupt handler for sending processing
+/* et131x_handle_send_pkts - Interrupt handler for sending processing
*
* Re-claim the send resources, complete sends and get more to send from
* the send wait queue.
*
* Assumption - Send spinlock has been acquired
*/
-static void et131x_handle_send_interrupt(struct et131x_adapter *adapter)
+static void et131x_handle_send_pkts(struct et131x_adapter *adapter)
{
unsigned long flags;
u32 serviced;
@@ -3708,9 +3714,9 @@ static void et131x_pci_remove(struct pci_dev *pdev)
struct et131x_adapter *adapter = netdev_priv(netdev);
unregister_netdev(netdev);
+ netif_napi_del(&adapter->napi);
phy_disconnect(adapter->phydev);
mdiobus_unregister(adapter->mii_bus);
- cancel_work_sync(&adapter->task);
kfree(adapter->mii_bus->irq);
mdiobus_free(adapter->mii_bus);
@@ -3790,6 +3796,7 @@ static irqreturn_t et131x_isr(int irq, void *dev_id)
bool handled = true;
struct net_device *netdev = (struct net_device *)dev_id;
struct et131x_adapter *adapter = netdev_priv(netdev);
+ struct address_map __iomem *iomem = adapter->regs;
struct rx_ring *rx_ring = &adapter->rx_ring;
struct tx_ring *tx_ring = &adapter->tx_ring;
u32 status;
@@ -3826,7 +3833,6 @@ static irqreturn_t et131x_isr(int irq, void *dev_id)
}
/* This is our interrupt, so process accordingly */
-
if (status & ET_INTR_WATCHDOG) {
struct tcb *tcb = tx_ring->send_head;
@@ -3842,54 +3848,8 @@ static irqreturn_t et131x_isr(int irq, void *dev_id)
status &= ~ET_INTR_WATCHDOG;
}
- if (!status) {
- /* This interrupt has in some way been "handled" by
- * the ISR. Either it was a spurious Rx interrupt, or
- * it was a Tx interrupt that has been filtered by
- * the ISR.
- */
- et131x_enable_interrupts(adapter);
- goto out;
- }
-
- /* We need to save the interrupt status value for use in our
- * DPC. We will clear the software copy of that in that
- * routine.
- */
- adapter->stats.interrupt_status = status;
-
- /* Schedule the ISR handler as a bottom-half task in the
- * kernel's tq_immediate queue, and mark the queue for
- * execution
- */
- schedule_work(&adapter->task);
-out:
- return IRQ_RETVAL(handled);
-}
-
-/* et131x_isr_handler - The ISR handler
- *
- * scheduled to run in a deferred context by the ISR. This is where the ISR's
- * work actually gets done.
- */
-static void et131x_isr_handler(struct work_struct *work)
-{
- struct et131x_adapter *adapter =
- container_of(work, struct et131x_adapter, task);
- u32 status = adapter->stats.interrupt_status;
- struct address_map __iomem *iomem = adapter->regs;
-
- /* These first two are by far the most common. Once handled, we clear
- * their two bits in the status word. If the word is now zero, we
- * exit.
- */
- /* Handle all the completed Transmit interrupts */
- if (status & ET_INTR_TXDMA_ISR)
- et131x_handle_send_interrupt(adapter);
-
- /* Handle all the completed Receives interrupts */
- if (status & ET_INTR_RXDMA_XFR_DONE)
- et131x_handle_recv_interrupt(adapter);
+ if (status & (ET_INTR_RXDMA_XFR_DONE | ET_INTR_TXDMA_ISR))
+ napi_schedule(&adapter->napi);
status &= ~(ET_INTR_TXDMA_ISR | ET_INTR_RXDMA_XFR_DONE);
@@ -4041,8 +4001,34 @@ static void et131x_isr_handler(struct work_struct *work)
* addressed module is in a power-down state and can't respond.
*/
}
+
+ if (!status) {
+ /* This interrupt has in some way been "handled" by
+ * the ISR. Either it was a spurious Rx interrupt, or
+ * it was a Tx interrupt that has been filtered by
+ * the ISR.
+ */
+ et131x_enable_interrupts(adapter);
+ }
+
out:
- et131x_enable_interrupts(adapter);
+ return IRQ_RETVAL(handled);
+}
+
+static int et131x_poll(struct napi_struct *napi, int budget)
+{
+ struct et131x_adapter *adapter =
+ container_of(napi, struct et131x_adapter, napi);
+ int work_done = et131x_handle_recv_pkts(adapter, budget);
+
+ et131x_handle_send_pkts(adapter);
+
+ if (work_done < budget) {
+ napi_complete(&adapter->napi);
+ et131x_enable_interrupts(adapter);
+ }
+
+ return work_done;
}
/* et131x_stats - Return the current device statistics */
@@ -4111,6 +4097,8 @@ static int et131x_open(struct net_device *netdev)
adapter->flags |= FMP_ADAPTER_INTERRUPT_IN_USE;
+ napi_enable(&adapter->napi);
+
et131x_up(netdev);
return result;
@@ -4122,6 +4110,7 @@ static int et131x_close(struct net_device *netdev)
struct et131x_adapter *adapter = netdev_priv(netdev);
et131x_down(netdev);
+ napi_disable(&adapter->napi);
adapter->flags &= ~FMP_ADAPTER_INTERRUPT_IN_USE;
free_irq(adapter->pdev->irq, netdev);
@@ -4502,8 +4491,7 @@ static int et131x_pci_setup(struct pci_dev *pdev,
/* Init send data structures */
et131x_init_send(adapter);
- /* Set up the task structure for the ISR's deferred handler */
- INIT_WORK(&adapter->task, et131x_isr_handler);
+ netif_napi_add(netdev, &adapter->napi, et131x_poll, 64);
/* Copy address into the net_device struct */
memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN);
--
2.1.0
^ permalink raw reply related
* Is it normal to have cross namespace symlinks?
From: Alexander Y. Fomichev @ 2014-08-21 10:38 UTC (permalink / raw)
To: netdev
Hello guys!
Recently i switched to 3.14.x stable branch and i've got a bunch of
warnings:
[ 44.717746] ------------[ cut here ]------------
[ 44.717750] WARNING: CPU: 1 PID: 7007 at fs/sysfs/dir.c:52
sysfs_warn_dup+0x86/0xa0() [ 44.717751] sysfs: cannot create
duplicate filename
'/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1/upper_eth1'
[ 37.759856] ------------[ cut here ]------------
[ 37.759863] WARNING: CPU: 1 PID: 3822 at fs/sysfs/dir.c:52
sysfs_warn_dup+0x86/0xa0() [ 37.759864] sysfs: cannot create
duplicate filename '/devices/virtual/net/bond0/upper_eth0'
....
It was triggered by renaming of macvlan interfaces in a freshly created
network namespaces. Just start two lxc containers one by one with
macvlans on the same lowerdev and rename devices inside containers (with
the same name) and voila.
I investigated problem a bit and i see that code in net/core/dev.c
which working with sysfs symlinks upper_dev / lower_dev is absolutely
unaware of namespaces. I mean code which uses functions
netdev_adjacent_sysfs_del,netdev_adjacent_sysfs_add
netdev_adjacent_rename_links,dev_change_name
just not takes into account that dev and adj_dev could be in a
different namespaces. If userland asks to rename interface in a
new namespace this code renames an upper_dev link
in a parent namespace accordingly. I hadn't tried but i'll
bet it works vice-versa as well. It leads to warnings i've wrote above
and also creation inside namespaces a pretty meaningless links:
/sys/devices/virtual/net/eth1/lower_eth1
-> ../../../pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1
or probably deletion of symlinks of a perfectly valid devices.
At the same time this issue is not affecting most of current
functionality and seems like nobody cares about that. I suspect that
there's (almost) no real users of sysfs uppder_dev/lower_dev simlinks,
am i right?
--
Best regards.
Alexander Y. Fomichev <Aleksandr.Fomichev@x5.ru>
+7-495-662-88-88 ext. 11346
^ permalink raw reply
* [PATCH net] cxgb4: Free completed tx skbs promptly
From: Hariprasad Shenai @ 2014-08-21 11:34 UTC (permalink / raw)
To: netdev; +Cc: davem, leedom, nirranjan, kumaras, anish, Hariprasad Shenai
Description of problem:
The NIC card is not reporting back to the driver the transmitted skbs,
so they get stuck in the TX ring causing issues with reference
counters in other kernel components.
Developed a new Automatic Egress Queue Update firmware facility to slowly tick
through Egress Queues and send back any outstanding CIDX Updates which are
laying around.
Based on original work by Casey Leedom <leedom@chelsio.com>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/sge.c | 3 ++-
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 1 +
drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 3 ++-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index b0bba32..d22d728 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -2303,7 +2303,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0));
c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC |
FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c));
- c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid));
+ c.viid_pkd = htonl(FW_EQ_ETH_CMD_AUTOEQUEQE |
+ FW_EQ_ETH_CMD_VIID(pi->viid));
c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) |
FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) |
FW_EQ_ETH_CMD_FETCHRO(1) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index 0549170..5f2729e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -1227,6 +1227,7 @@ struct fw_eq_eth_cmd {
#define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16)
#define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0)
+#define FW_EQ_ETH_CMD_AUTOEQUEQE (1U << 30)
#define FW_EQ_ETH_CMD_VIID(x) ((x) << 16)
struct fw_eq_ctrl_cmd {
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index bdfa80c..a5fb949 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -2250,7 +2250,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq,
cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC |
FW_EQ_ETH_CMD_EQSTART |
FW_LEN16(cmd));
- cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_VIID(pi->viid));
+ cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_AUTOEQUEQE |
+ FW_EQ_ETH_CMD_VIID(pi->viid));
cmd.fetchszm_to_iqid =
cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) |
FW_EQ_ETH_CMD_PCIECHN(pi->port_id) |
--
1.7.1
^ permalink raw reply related
* Re: [PATCH net v2] cxgb4: Fix race condition in cleanup
From: Neil Horman @ 2014-08-21 11:54 UTC (permalink / raw)
To: Anish Bhatt; +Cc: netdev, davem, hariprasad, leedom, svemuri
In-Reply-To: <1408567446-6598-1-git-send-email-anish@chelsio.com>
On Wed, Aug 20, 2014 at 01:44:06PM -0700, Anish Bhatt wrote:
> There is a possible race condition when we unregister the PCI Driver and then
> flush/destroy the global "workq". This could lead to situations where there
> are tasks on the Work Queue with references to now deleted adapter data
> structures. Instead, have per-adapter Work Queues which were instantiated and
> torn down in init_one() and remove_one(), respectively.
>
> v2: Remove unnecessary call to flush_workqueue() before destroy_workqueue()
>
> Signed-off-by: Anish Bhatt <anish@chelsio.com>
> Signed-off-by: Casey Leedom <leedom@chelsio.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
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;
as well as URLs for NNTP newsgroup(s).