* Re: [PATCH net-next-2.6 v3] can: Topcliff: PCH_CAN driver: Add Flow control,
From: Tomoya MORINAGA @ 2010-11-19 6:18 UTC (permalink / raw)
To: Marc Kleine-Budde
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w, Masayuki Ohtake,
Samuel Ortiz, margie.foster-ral2JQCrhuEAvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w, Wolfgang Grandegger,
joel.clark-ral2JQCrhuEAvxtiuMwx3w, David S. Miller,
Christian Pellegrin, qi.wang-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <4CE27796.2000206@pengutronix.de>
On Tuesday, November 16, 2010 9:22 PM, Marc Kleine-Budde wrote :
Except the following, I have updated/resubmitted already .
>> static int pch_can_rx_poll(struct napi_struct *napi, int quota)
>> {
>> struct net_device *ndev = napi->dev;
>> struct pch_can_priv *priv = netdev_priv(ndev);
>> - struct net_device_stats *stats = &(priv->ndev->stats);
>> - u32 dlc;
>> u32 int_stat;
>> int rcv_pkts = 0;
^^^^
>can be removed...if you remove the += below
Since there is "goto" code, "=0" is better.
>> - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
>> + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no);
>Still we have the busy waiting in the TX path. Maybe you can move the
>waiting before accessing the if[1] and remove the busy waiting here.
I can't understand your saying.
For transmitting data, calling pch_can_rw_msg_obj is mandatory.
---
Thanks,
Tomoya MORINAGA
OKI SEMICONDUCTOR CO., LTD.
^ permalink raw reply
* Re: [RFC PATCH] netfilter: remove the duplicate tables
From: Eric Dumazet @ 2010-11-19 6:24 UTC (permalink / raw)
To: Changli Gao; +Cc: Patrick McHardy, David S. Miller, netfilter-devel, netdev
In-Reply-To: <AANLkTi=w8vvVNYMa5D-_4UDoVJABbvM9CVYjABrVoWPY@mail.gmail.com>
Le vendredi 19 novembre 2010 à 07:36 +0800, Changli Gao a écrit :
> On Thu, Nov 18, 2010 at 11:43 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > You consume 16 bytes per counter in the main table, while 4 bytes index
> > should be enough on SMP build. Most firewalls I know use two or four
> > cpus at most.
>
> I think we can't change the structure of ipt_entry, as it is exposed
> to userspace as an ABI. Though there is no need to keep the same
> structure in the kernel space, converting is a big work. :)
>
We already do that for COMPAT. This is a not a big deal to always use a
converter and make it dependent on userland being 32 or 64 bit.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] net: reduce the lines of code
From: Hagen Paul Pfeifer @ 2010-11-19 6:35 UTC (permalink / raw)
To: Changli Gao; +Cc: David S. Miller, netdev
In-Reply-To: <1290132284-12328-1-git-send-email-xiaosuo@gmail.com>
On Fri, 19 Nov 2010 10:04:44 +0800, Changli Gao <xiaosuo@gmail.com> wrote:
> Use macros to reduce the regularity lines.
This is complete awkward and does not fix anything - on the contrary it
makes it harder to understand the code and no advantage is achieved.
Hagen
^ permalink raw reply
* Re: [PATCH] net: reduce the lines of code
From: Changli Gao @ 2010-11-19 7:17 UTC (permalink / raw)
To: Hagen Paul Pfeifer; +Cc: David S. Miller, netdev
In-Reply-To: <b2c34db84e88366e465af590900ae3db@localhost>
On Fri, Nov 19, 2010 at 2:35 PM, Hagen Paul Pfeifer <hagen@jauu.net> wrote:
>
> On Fri, 19 Nov 2010 10:04:44 +0800, Changli Gao <xiaosuo@gmail.com> wrote:
>> Use macros to reduce the regularity lines.
>
> This is complete awkward and does not fix anything - on the contrary it
> makes it harder to understand the code and no advantage is achieved.
>
Although it doesn't fix anything, It can simplify the adding of new
BPF instructions, one place in filter_def.h instead of two in
filter.c. I think if some code can be generated automatically, we'd
better not write it manually, as the chance of error is less when the
code is generated automatically.
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* Re: [PATCH net-next-2.6 v2] can: Topcliff: PCH_CAN driver: Add Flow control,
From: Tomoya MORINAGA @ 2010-11-19 7:36 UTC (permalink / raw)
To: Wolfgang Grandegger
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w, Masayuki Ohtake,
Samuel Ortiz, margie.foster-ral2JQCrhuEAvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
joel.clark-ral2JQCrhuEAvxtiuMwx3w, David S. Miller,
Christian Pellegrin, qi.wang-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <4CE259FB.5090402@grandegger.com>
On Tuesday, November 16, 2010 7:16 PM, Wolfgang Grandegger wrote :
> > ......It seems the same line continues forever.
>
> Yes, it will continue until you connect the cable, that's normal
> behavior. But that's not the full sequence. Could you please repeat the
> test as shown below:
>
> First start the following command in a *separate* session.
> # candump any,0:0,#FFFFFFFF"
>
> Then setup and start the CAN controller:
> # ip link set can0 up type can bitrate 125000
> # cansend can0 123#deadbeef
>
I show the result of the above command below,
[root@localhost can-utils]# candump any,0:0,#FFFFFFFF
can0 20000020 [8] 00 00 00 00 00 00 08 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 10 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 18 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 20 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 28 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 30 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 38 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 40 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 48 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 50 00 ERRORFRAME
can0 20000020 [8] 00 00 00 00 00 00 58 00 ERRORFRAME
can0 20000024 [8] 00 00 00 00 00 00 60 00 ERRORFRAME
can0 20000024 [8] 00 08 00 00 00 00 68 00 ERRORFRAME
can0 20000024 [8] 00 08 00 00 00 00 70 00 ERRORFRAME
can0 20000024 [8] 00 08 00 00 00 00 78 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
.....continue forever
------
Thanks,
Tomoya MORINAGA
OKI SEMICONDUCTOR CO., LTD.
^ permalink raw reply
* Re: [PATCH] net: reduce the lines of code
From: Eric Dumazet @ 2010-11-19 7:51 UTC (permalink / raw)
To: Changli Gao; +Cc: Hagen Paul Pfeifer, David S. Miller, netdev
In-Reply-To: <AANLkTinccn2Biwh7d6d4kZJrJTgGbLjKApi2+dwGnvVL@mail.gmail.com>
Le vendredi 19 novembre 2010 à 15:17 +0800, Changli Gao a écrit :
> On Fri, Nov 19, 2010 at 2:35 PM, Hagen Paul Pfeifer <hagen@jauu.net> wrote:
> >
> > On Fri, 19 Nov 2010 10:04:44 +0800, Changli Gao <xiaosuo@gmail.com> wrote:
> >> Use macros to reduce the regularity lines.
> >
> > This is complete awkward and does not fix anything - on the contrary it
> > makes it harder to understand the code and no advantage is achieved.
> >
>
> Although it doesn't fix anything, It can simplify the adding of new
> BPF instructions, one place in filter_def.h instead of two in
> filter.c. I think if some code can be generated automatically, we'd
> better not write it manually, as the chance of error is less when the
> code is generated automatically.
>
Idea is good, but the way you did it is not.
I have two patches in testing. I'll post them today.
One to remove all the "+ 1" we do in codes[] init
One at check time to replace the divide by a constant instruction
(DIV_K) by a reciprocal one (a multiply at exec time)
^ permalink raw reply
* [PATCH net-next-2.6] filter: cleanup codes[] init
From: Eric Dumazet @ 2010-11-19 7:56 UTC (permalink / raw)
To: David S. Miller; +Cc: Hagen Paul Pfeifer, netdev, Changli Gao
In-Reply-To: <1290153111.29509.2.camel@edumazet-laptop>
Starting the translated instruction to 1 instead of 0 allows us to
remove one descrement at check time and makes codes[] array init
cleaner.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/core/filter.c | 95 +++++++++++++++++++++-----------------------
1 file changed, 47 insertions(+), 48 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index 15a545d..a1edb5d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -39,7 +39,7 @@
#include <linux/filter.h>
enum {
- BPF_S_RET_K = 0,
+ BPF_S_RET_K = 1,
BPF_S_RET_A,
BPF_S_ALU_ADD_K,
BPF_S_ALU_ADD_X,
@@ -436,51 +436,51 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
* Invalid instructions are initialized to 0.
*/
static const u8 codes[] = {
- [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K + 1,
- [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X + 1,
- [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K + 1,
- [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X + 1,
- [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K + 1,
- [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X + 1,
- [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X + 1,
- [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K + 1,
- [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X + 1,
- [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K + 1,
- [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X + 1,
- [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K + 1,
- [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X + 1,
- [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K + 1,
- [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X + 1,
- [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG + 1,
- [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS + 1,
- [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS + 1,
- [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS + 1,
- [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN + 1,
- [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND + 1,
- [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND + 1,
- [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND + 1,
- [BPF_LD|BPF_IMM] = BPF_S_LD_IMM + 1,
- [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN + 1,
- [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH + 1,
- [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM + 1,
- [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX + 1,
- [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA + 1,
- [BPF_RET|BPF_K] = BPF_S_RET_K + 1,
- [BPF_RET|BPF_A] = BPF_S_RET_A + 1,
- [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K + 1,
- [BPF_LD|BPF_MEM] = BPF_S_LD_MEM + 1,
- [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM + 1,
- [BPF_ST] = BPF_S_ST + 1,
- [BPF_STX] = BPF_S_STX + 1,
- [BPF_JMP|BPF_JA] = BPF_S_JMP_JA + 1,
- [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K + 1,
- [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X + 1,
- [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K + 1,
- [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X + 1,
- [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K + 1,
- [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X + 1,
- [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K + 1,
- [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X + 1,
+ [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K,
+ [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X,
+ [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K,
+ [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X,
+ [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K,
+ [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X,
+ [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X,
+ [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K,
+ [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X,
+ [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K,
+ [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X,
+ [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K,
+ [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X,
+ [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K,
+ [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X,
+ [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG,
+ [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS,
+ [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS,
+ [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS,
+ [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN,
+ [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND,
+ [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND,
+ [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND,
+ [BPF_LD|BPF_IMM] = BPF_S_LD_IMM,
+ [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN,
+ [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH,
+ [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM,
+ [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX,
+ [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA,
+ [BPF_RET|BPF_K] = BPF_S_RET_K,
+ [BPF_RET|BPF_A] = BPF_S_RET_A,
+ [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K,
+ [BPF_LD|BPF_MEM] = BPF_S_LD_MEM,
+ [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM,
+ [BPF_ST] = BPF_S_ST,
+ [BPF_STX] = BPF_S_STX,
+ [BPF_JMP|BPF_JA] = BPF_S_JMP_JA,
+ [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K,
+ [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X,
+ [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K,
+ [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X,
+ [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K,
+ [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X,
+ [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K,
+ [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X,
};
int pc;
@@ -495,8 +495,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
if (code >= ARRAY_SIZE(codes))
return -EINVAL;
code = codes[code];
- /* Undo the '+ 1' in codes[] after validation. */
- if (!code--)
+ if (!code)
return -EINVAL;
/* Some instructions need special checks */
switch (code) {
^ permalink raw reply related
* [PATCH net-next-2.6] filter: use reciprocal divide
From: Eric Dumazet @ 2010-11-19 8:04 UTC (permalink / raw)
To: David S. Miller; +Cc: Hagen Paul Pfeifer, netdev, Changli Gao
In-Reply-To: <1290153398.29509.7.camel@edumazet-laptop>
At compile time, we can replace the DIV_K instruction (divide by a
constant value) by a reciprocal divide.
At exec time, the expensive divide is replaced by a multiply, a less
expensive operation on most processors.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/core/filter.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index a1edb5d..13853c7 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -37,6 +37,7 @@
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <linux/filter.h>
+#include <linux/reciprocal_div.h>
enum {
BPF_S_RET_K = 1,
@@ -202,7 +203,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
A /= X;
continue;
case BPF_S_ALU_DIV_K:
- A /= f_k;
+ A = reciprocal_divide(A, f_k);
continue;
case BPF_S_ALU_AND_X:
A &= X;
@@ -503,6 +504,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
/* check for division by zero */
if (ftest->k == 0)
return -EINVAL;
+ ftest->k = reciprocal_value(ftest->k);
break;
case BPF_S_LD_MEM:
case BPF_S_LDX_MEM:
^ permalink raw reply related
* Re: sound playback became chopping on nfs rootfs
From: Kuninori Morimoto @ 2010-11-19 8:08 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: Linux-Net, Linux-ALSA, Chuck Lever
In-Reply-To: <4CE4EBE8.8030702@ladisch.de>
Dear Clemens
Thank you for your comment
> Apparently, the latest kernel uses different mount options.
>
> Try to find out what mount options your root FS had in the old kernel,
> and manually set them in some startup script.
OK. Thanks. I try it.
Does this "mount options" mean root_mountflags ?
If not, can you please which one ?
My rootfs is mounted as NFS when boot.
CONFIG_ROOT_NFS=y
CONFIG_IP_PNP_DHCP=y
CONFIG_CMDLINE="... rootfs=/dev/nfs ip=dhcp"
Best regards
--
Kuninori Morimoto
^ permalink raw reply
* Re: [alsa-devel] sound playback became chopping on nfs rootfs
From: Clemens Ladisch @ 2010-11-19 8:15 UTC (permalink / raw)
To: Kuninori Morimoto; +Cc: Linux-Net, Linux-ALSA, Chuck Lever
In-Reply-To: <w3p39qx4ty8.wl%kuninori.morimoto.gx@renesas.com>
Kuninori Morimoto wrote:
> > Apparently, the latest kernel uses different mount options.
> >
> > Try to find out what mount options your root FS had in the old kernel,
> > and manually set them in some startup script.
>
> OK. Thanks. I try it.
> Does this "mount options" mean root_mountflags ?
No; the defaults for options that are not set in root_mountflags
have changed.
Try /proc/mounts.
Regards,
Clemens
^ permalink raw reply
* Re: [PATCH net-next-2.6] filter: use reciprocal divide
From: Changli Gao @ 2010-11-19 8:18 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, Hagen Paul Pfeifer, netdev
In-Reply-To: <1290153886.29509.10.camel@edumazet-laptop>
On Fri, Nov 19, 2010 at 4:04 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> At compile time, we can replace the DIV_K instruction (divide by a
> constant value) by a reciprocal divide.
>
> At exec time, the expensive divide is replaced by a multiply, a less
> expensive operation on most processors.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Changli Gao <xiaosuo@gmail.com>
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* Re: [PATCH net-next-2.6] filter: cleanup codes[] init
From: Changli Gao @ 2010-11-19 8:38 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, Hagen Paul Pfeifer, netdev
In-Reply-To: <1290153398.29509.7.camel@edumazet-laptop>
On Fri, Nov 19, 2010 at 3:56 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Starting the translated instruction to 1 instead of 0 allows us to
> remove one descrement at check time and makes codes[] array init
> cleaner.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> ---
> net/core/filter.c | 95 +++++++++++++++++++++-----------------------
> 1 file changed, 47 insertions(+), 48 deletions(-)
>
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 15a545d..a1edb5d 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -39,7 +39,7 @@
> #include <linux/filter.h>
>
> enum {
> - BPF_S_RET_K = 0,
> + BPF_S_RET_K = 1,
> BPF_S_RET_A,
> BPF_S_ALU_ADD_K,
> BPF_S_ALU_ADD_X,
> @@ -436,51 +436,51 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
> * Invalid instructions are initialized to 0.
> */
> static const u8 codes[] = {
> - [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K + 1,
> - [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X + 1,
> - [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K + 1,
> - [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X + 1,
> - [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K + 1,
> - [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X + 1,
> - [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X + 1,
> - [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K + 1,
> - [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X + 1,
> - [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K + 1,
> - [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X + 1,
> - [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K + 1,
> - [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X + 1,
> - [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K + 1,
> - [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X + 1,
> - [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG + 1,
> - [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS + 1,
> - [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS + 1,
> - [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS + 1,
> - [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN + 1,
> - [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND + 1,
> - [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND + 1,
> - [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND + 1,
> - [BPF_LD|BPF_IMM] = BPF_S_LD_IMM + 1,
> - [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN + 1,
> - [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH + 1,
> - [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM + 1,
> - [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX + 1,
> - [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA + 1,
> - [BPF_RET|BPF_K] = BPF_S_RET_K + 1,
> - [BPF_RET|BPF_A] = BPF_S_RET_A + 1,
> - [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K + 1,
> - [BPF_LD|BPF_MEM] = BPF_S_LD_MEM + 1,
> - [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM + 1,
> - [BPF_ST] = BPF_S_ST + 1,
> - [BPF_STX] = BPF_S_STX + 1,
> - [BPF_JMP|BPF_JA] = BPF_S_JMP_JA + 1,
> - [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K + 1,
> - [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X + 1,
> - [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K + 1,
> - [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X + 1,
> - [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K + 1,
> - [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X + 1,
> - [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K + 1,
> - [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X + 1,
> + [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K,
> + [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X,
> + [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K,
> + [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X,
> + [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K,
> + [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X,
> + [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X,
> + [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K,
> + [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X,
> + [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K,
> + [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X,
> + [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K,
> + [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X,
> + [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K,
> + [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X,
> + [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG,
> + [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS,
> + [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS,
> + [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS,
> + [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN,
> + [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND,
> + [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND,
> + [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND,
> + [BPF_LD|BPF_IMM] = BPF_S_LD_IMM,
> + [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN,
> + [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH,
> + [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM,
> + [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX,
> + [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA,
> + [BPF_RET|BPF_K] = BPF_S_RET_K,
> + [BPF_RET|BPF_A] = BPF_S_RET_A,
> + [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K,
> + [BPF_LD|BPF_MEM] = BPF_S_LD_MEM,
> + [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM,
> + [BPF_ST] = BPF_S_ST,
> + [BPF_STX] = BPF_S_STX,
> + [BPF_JMP|BPF_JA] = BPF_S_JMP_JA,
> + [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K,
> + [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X,
> + [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K,
> + [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X,
> + [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K,
> + [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X,
> + [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K,
> + [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X,
> };
> int pc;
>
> @@ -495,8 +495,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
> if (code >= ARRAY_SIZE(codes))
> return -EINVAL;
> code = codes[code];
> - /* Undo the '+ 1' in codes[] after validation. */
> - if (!code--)
> + if (!code)
> return -EINVAL;
> /* Some instructions need special checks */
> switch (code) {
>
>
>
I compared the asm code of sk_run_filter.
Here is the original:
switch (fentry->code) {
ffffffff8138c70c: 66 83 38 2c cmpw $0x2c,(%rax)
/*
* Process array of filter instructions.
*/
for (pc = 0; pc < flen; pc++) {
const struct sock_filter *fentry = &filter[pc];
u32 f_k = fentry->k;
ffffffff8138c710: 44 8b 78 04 mov 0x4(%rax),%r15d
switch (fentry->code) {
ffffffff8138c714: 0f 87 53 02 00 00 ja
ffffffff8138c96d <sk_run_filter+0x2a8>
ffffffff8138c71a: 0f b7 10 movzwl (%rax),%edx
ffffffff8138c71d: ff 24 d5 00 00 00 00 jmpq *0x0(,%rdx,8)
And here is the patched:
switch (fentry->code) {
ffffffff8138c708: 8b 10 mov (%rax),%edx
/*
* Process array of filter instructions.
*/
for (pc = 0; pc < flen; pc++) {
const struct sock_filter *fentry = &filter[pc];
u32 f_k = fentry->k;
ffffffff8138c70a: 44 8b 78 04 mov 0x4(%rax),%r15d
switch (fentry->code) {
ffffffff8138c70e: ff ca dec %edx
ffffffff8138c710: 66 83 fa 2c cmp $0x2c,%dx
ffffffff8138c714: 0f 87 53 02 00 00 ja
ffffffff8138c96d <sk_run_filter+0x2ac>
ffffffff8138c71a: 0f b7 d2 movzwl %dx,%edx
ffffffff8138c71d: ff 24 d5 00 00 00 00 jmpq *0x0(,%rdx,8)
As you see, an additional 'dec %edx' instruction is inserted.
sk_chk_filter() only runs 1 times, I think we can afford the 'dec
instruction' and 'dirty' code, but sk_run_filter() runs much often,
this additional dec instruction isn't affordable.
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* Do you need a loan at 3%?(serious inquiries only)
From: Mr Gordon Ferrari @ 2010-11-18 15:25 UTC (permalink / raw)
To: alikogroup
Do you need a loan to Start up Business? Loan to Pay off Bill Contact us
for a loan application at 3% via Email:gordonflinc1@aol.co.uk
^ permalink raw reply
* Re: [PATCH net-next-2.6 v2] can: Topcliff: PCH_CAN driver: Add Flow control,
From: Wolfgang Grandegger @ 2010-11-19 8:57 UTC (permalink / raw)
To: Tomoya MORINAGA
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w, Masayuki Ohtake,
Samuel Ortiz, margie.foster-ral2JQCrhuEAvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
joel.clark-ral2JQCrhuEAvxtiuMwx3w, David S. Miller,
Christian Pellegrin, qi.wang-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <00bf01cb87bc$8ed6e300$66f8800a-a06+6cuVnkTSQfdrb5gaxUEOCMrvLtNR@public.gmane.org>
Hi Tomoya,
On 11/19/2010 08:36 AM, Tomoya MORINAGA wrote:
> On Tuesday, November 16, 2010 7:16 PM, Wolfgang Grandegger wrote :
>
>>> ......It seems the same line continues forever.
>>
>> Yes, it will continue until you connect the cable, that's normal
>> behavior. But that's not the full sequence. Could you please repeat the
>> test as shown below:
>>
>> First start the following command in a *separate* session.
>> # candump any,0:0,#FFFFFFFF"
>>
>> Then setup and start the CAN controller:
>> # ip link set can0 up type can bitrate 125000
>> # cansend can0 123#deadbeef
>>
>
> I show the result of the above command below,
>
> [root@localhost can-utils]# candump any,0:0,#FFFFFFFF
> can0 20000020 [8] 00 00 00 00 00 00 08 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 10 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 18 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 20 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 28 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 30 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 38 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 40 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 48 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 50 00 ERRORFRAME
> can0 20000020 [8] 00 00 00 00 00 00 58 00 ERRORFRAME
The above lines describe bus errors. Therefore it should be
can0 20000088 [8] 00 00 80 19 00 00 58 00 ERRORFRAME
> can0 20000024 [8] 00 00 00 00 00 00 60 00 ERRORFRAME
The TX error counter has reached 96 signaling a can error state change
to "error warning".
> can0 20000024 [8] 00 08 00 00 00 00 68 00 ERRORFRAME
CAN_ERR_CRTL in the id and CAN_ERR_CRTL_TX_WARNING in data[1], but ...
> can0 20000024 [8] 00 08 00 00 00 00 70 00 ERRORFRAME
the state change should be signaled only *once*.
> can0 20000024 [8] 00 08 00 00 00 00 78 00 ERRORFRAME
> can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
"Error passive" state is reached and CAN_ERR_CRTL_TX_PASSIVE sould be
set in data[1], but CAN_ERR_CRTL_TX_WARNING should be removed.
> can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
> can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
> can0 20000024 [8] 00 28 00 00 00 00 80 00 ERRORFRAME
Sounds magic, well, I'm going to prepare a patch as soon as your pending
patch series is applied.
Could you please do the same testing while triggering a bus-off? After
the test, the output of "ip -d -s link" would be interesting as well.
Thanks,
Wolfgang.
^ permalink raw reply
* Re: [PATCH net-next-2.6 v3] can: Topcliff: PCH_CAN driver: Add Flow control,
From: Marc Kleine-Budde @ 2010-11-19 9:20 UTC (permalink / raw)
To: Tomoya MORINAGA
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w, Samuel Ortiz,
margie.foster-ral2JQCrhuEAvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA, Christian Pellegrin,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w, Masayuki Ohtake,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
joel.clark-ral2JQCrhuEAvxtiuMwx3w, David S. Miller,
Wolfgang Grandegger, qi.wang-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <007401cb87b1$a773b3d0$66f8800a-a06+6cuVnkTSQfdrb5gaxUEOCMrvLtNR@public.gmane.org>
[-- Attachment #1.1: Type: text/plain, Size: 1459 bytes --]
On 11/19/2010 07:18 AM, Tomoya MORINAGA wrote:
> On Tuesday, November 16, 2010 9:22 PM, Marc Kleine-Budde wrote :
>
> Except the following, I have updated/resubmitted already .
>
>>> static int pch_can_rx_poll(struct napi_struct *napi, int quota)
>>> {
>>> struct net_device *ndev = napi->dev;
>>> struct pch_can_priv *priv = netdev_priv(ndev);
>>> - struct net_device_stats *stats = &(priv->ndev->stats);
>>> - u32 dlc;
>>> u32 int_stat;
>>> int rcv_pkts = 0;
> ^^^^
>> can be removed...if you remove the += below
> Since there is "goto" code, "=0" is better.
The compiler would complain, if there's an unused variable.
>>> - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
>>> + pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no);
>> Still we have the busy waiting in the TX path. Maybe you can move the
>> waiting before accessing the if[1] and remove the busy waiting here.
> I can't understand your saying.
> For transmitting data, calling pch_can_rw_msg_obj is mandatory.
Yes, but the busy wait is not needed. It should be enough to do the
busy-waiting _before_ accessing the if[1].
cheers, Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
[-- Attachment #2: Type: text/plain, Size: 188 bytes --]
_______________________________________________
Socketcan-core mailing list
Socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-core
^ permalink raw reply
* Re: [PATCH net-next-2.6 1/17] can: EG20T PCH: Separate Interface Register(IF1/IF2)
From: Marc Kleine-Budde @ 2010-11-19 9:26 UTC (permalink / raw)
To: Tomoya MORINAGA
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w, Samuel Ortiz,
margie.foster-ral2JQCrhuEAvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w, Wolfgang Grandegger,
joel.clark-ral2JQCrhuEAvxtiuMwx3w, David S. Miller,
Christian Pellegrin, qi.wang-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <4CE60E8B.5090104-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
[-- Attachment #1.1: Type: text/plain, Size: 30823 bytes --]
On 11/19/2010 06:43 AM, Tomoya MORINAGA wrote:
> Separate interface register from whole of register structure.
> CAN register of Intel PCH EG20T has 2 sets of interface register.
> To reduce whole of code size, separate interface register.
> As a result, the number of function also can be reduced.
Looks good, use enums for PCH_{RX,TX}_IFREG, here not in a later patch.
cheers, Marc
> Signed-off-by: Tomoya MORINAGA <tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
> ---
> drivers/net/can/pch_can.c | 442 ++++++++++++++++++++-------------------------
> 1 files changed, 198 insertions(+), 244 deletions(-)
>
> diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
> index 238622a..143f100 100644
> --- a/drivers/net/can/pch_can.c
> +++ b/drivers/net/can/pch_can.c
> @@ -102,6 +102,9 @@
> #define PCH_MSK_CTRL_IE_SIE_EIE 0x07
> #define PCH_COUNTER_LIMIT 10
>
> +#define PCH_RX_IFREG 0
> +#define PCH_TX_IFREG 1
Please use enum here.
(I know, there's a later patch that fixes this.)
> +
> #define PCH_CAN_CLK 50000000 /* 50MHz */
>
> /* Define the number of message object.
> @@ -122,6 +125,21 @@ enum pch_can_mode {
> PCH_CAN_RUN
> };
>
> +struct pch_can_if_regs {
> + u32 creq;
> + u32 cmask;
> + u32 mask1;
> + u32 mask2;
> + u32 id1;
> + u32 id2;
> + u32 mcont;
> + u32 dataa1;
> + u32 dataa2;
> + u32 datab1;
> + u32 datab2;
> + u32 rsv[13];
> +};
> +
> struct pch_can_regs {
> u32 cont;
> u32 stat;
> @@ -130,38 +148,21 @@ struct pch_can_regs {
> u32 intr;
> u32 opt;
> u32 brpe;
> - u32 reserve1;
> - u32 if1_creq;
> - u32 if1_cmask;
> - u32 if1_mask1;
> - u32 if1_mask2;
> - u32 if1_id1;
> - u32 if1_id2;
> - u32 if1_mcont;
> - u32 if1_dataa1;
> - u32 if1_dataa2;
> - u32 if1_datab1;
> - u32 if1_datab2;
> - u32 reserve2;
> - u32 reserve3[12];
> - u32 if2_creq;
> - u32 if2_cmask;
> - u32 if2_mask1;
> - u32 if2_mask2;
> - u32 if2_id1;
> - u32 if2_id2;
> - u32 if2_mcont;
> - u32 if2_dataa1;
> - u32 if2_dataa2;
> - u32 if2_datab1;
> - u32 if2_datab2;
> - u32 reserve4;
> - u32 reserve5[20];
> + u32 reserve;
> + struct pch_can_if_regs ifregs[2]; /* [0]=if1 [1]=if2 */
> + u32 reserve1[8];
> u32 treq1;
> u32 treq2;
> - u32 reserve6[2];
> - u32 reserve7[56];
> - u32 reserve8[3];
> + u32 reserve2[6];
> + u32 data1;
> + u32 data2;
> + u32 reserve3[6];
> + u32 canipend1;
> + u32 canipend2;
> + u32 reserve4[6];
> + u32 canmval1;
> + u32 canmval2;
> + u32 reserve5[37];
> u32 srst;
> };
>
> @@ -303,143 +304,86 @@ static void pch_can_check_if_busy(u32 __iomem *creq_addr, u32 num)
> pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__);
> }
>
> -static void pch_can_set_rx_enable(struct pch_can_priv *priv, u32 buff_num,
> - u32 set)
> +static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num,
> + u32 set, u32 dir)
^^^
use the enum here, too
> {
> unsigned long flags;
> + u32 ie;
> +
> + if (dir)
> + ie = PCH_IF_MCONT_TXIE;
> + else
> + ie = PCH_IF_MCONT_RXIE;
>
> spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> /* Reading the receive buffer data from RAM to Interface1 registers */
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, buff_num);
> + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num);
>
> /* Setting the IF1MASK1 register to access MsgVal and RxIE bits */
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL,
> - &priv->regs->if1_cmask);
> + &priv->regs->ifregs[dir].cmask);
>
> if (set == PCH_ENABLE) {
> /* Setting the MsgVal and RxIE bits */
> - pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE);
> - pch_can_bit_set(&priv->regs->if1_id2, PCH_ID_MSGVAL);
> + pch_can_bit_set(&priv->regs->ifregs[dir].mcont, ie);
> + pch_can_bit_set(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL);
>
> } else if (set == PCH_DISABLE) {
> /* Resetting the MsgVal and RxIE bits */
> - pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE);
> - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID_MSGVAL);
> + pch_can_bit_clear(&priv->regs->ifregs[dir].mcont, ie);
> + pch_can_bit_clear(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL);
> }
>
> - pch_can_check_if_busy(&priv->regs->if1_creq, buff_num);
> + pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num);
> spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> }
>
> -static void pch_can_rx_enable_all(struct pch_can_priv *priv)
> -{
> - int i;
> -
> - /* Traversing to obtain the object configured as receivers. */
> - for (i = 0; i < PCH_OBJ_NUM; i++) {
> - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX)
> - pch_can_set_rx_enable(priv, i + 1, PCH_ENABLE);
> - }
> -}
>
> -static void pch_can_rx_disable_all(struct pch_can_priv *priv)
> +static void pch_can_set_rx_all(struct pch_can_priv *priv, u32 set)
> {
> int i;
>
> /* Traversing to obtain the object configured as receivers. */
> for (i = 0; i < PCH_OBJ_NUM; i++) {
> if (priv->msg_obj[i] == PCH_MSG_OBJ_RX)
> - pch_can_set_rx_enable(priv, i + 1, PCH_DISABLE);
> + pch_can_set_rxtx(priv, i + 1, set, PCH_RX_IFREG);
> }
> }
>
> -static void pch_can_set_tx_enable(struct pch_can_priv *priv, u32 buff_num,
> - u32 set)
> -{
> - unsigned long flags;
> -
> - spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> - /* Reading the Msg buffer from Message RAM to Interface2 registers. */
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
> - pch_can_check_if_busy(&priv->regs->if2_creq, buff_num);
> -
> - /* Setting the IF2CMASK register for accessing the
> - MsgVal and TxIE bits */
> - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL,
> - &priv->regs->if2_cmask);
> -
> - if (set == PCH_ENABLE) {
> - /* Setting the MsgVal and TxIE bits */
> - pch_can_bit_set(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE);
> - pch_can_bit_set(&priv->regs->if2_id2, PCH_ID_MSGVAL);
> - } else if (set == PCH_DISABLE) {
> - /* Resetting the MsgVal and TxIE bits. */
> - pch_can_bit_clear(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE);
> - pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID_MSGVAL);
> - }
> -
> - pch_can_check_if_busy(&priv->regs->if2_creq, buff_num);
> - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> -}
> -
> -static void pch_can_tx_enable_all(struct pch_can_priv *priv)
> -{
> - int i;
> -
> - /* Traversing to obtain the object configured as transmit object. */
> - for (i = 0; i < PCH_OBJ_NUM; i++) {
> - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX)
> - pch_can_set_tx_enable(priv, i + 1, PCH_ENABLE);
> - }
> -}
> -
> -static void pch_can_tx_disable_all(struct pch_can_priv *priv)
> +static void pch_can_set_tx_all(struct pch_can_priv *priv, u32 set)
> {
> int i;
>
> /* Traversing to obtain the object configured as transmit object. */
> for (i = 0; i < PCH_OBJ_NUM; i++) {
> if (priv->msg_obj[i] == PCH_MSG_OBJ_TX)
> - pch_can_set_tx_enable(priv, i + 1, PCH_DISABLE);
> + pch_can_set_rxtx(priv, i + 1, set, PCH_ENABLE);
> }
> }
>
> -static void pch_can_get_rx_enable(struct pch_can_priv *priv, u32 buff_num,
> - u32 *enable)
> +static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, u32 dir)
> {
> unsigned long flags;
> + u32 ie, enable;
>
> - spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, buff_num);
> -
> - if (((ioread32(&priv->regs->if1_id2)) & PCH_ID_MSGVAL) &&
> - ((ioread32(&priv->regs->if1_mcont)) &
> - PCH_IF_MCONT_RXIE))
> - *enable = PCH_ENABLE;
> + if (dir)
> + ie = PCH_IF_MCONT_RXIE;
> else
> - *enable = PCH_DISABLE;
> - spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> -}
> -
> -static void pch_can_get_tx_enable(struct pch_can_priv *priv, u32 buff_num,
> - u32 *enable)
> -{
> - unsigned long flags;
> + ie = PCH_IF_MCONT_TXIE;
>
> spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
> - pch_can_check_if_busy(&priv->regs->if2_creq, buff_num);
> + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[dir].creq, buff_num);
>
> - if (((ioread32(&priv->regs->if2_id2)) & PCH_ID_MSGVAL) &&
> - ((ioread32(&priv->regs->if2_mcont)) &
> - PCH_IF_MCONT_TXIE)) {
> - *enable = PCH_ENABLE;
> + if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) &&
> + ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie)) {
> + enable = PCH_ENABLE;
> } else {
> - *enable = PCH_DISABLE;
> + enable = PCH_DISABLE;
> }
> spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> + return enable;
> }
>
> static int pch_can_int_pending(struct pch_can_priv *priv)
> @@ -453,15 +397,17 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv,
> unsigned long flags;
>
> spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num);
> - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, &priv->regs->if1_cmask);
> + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num);
> + iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL,
> + &priv->regs->ifregs[0].cmask);
> if (set == PCH_ENABLE)
> - pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB);
> + pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
> + PCH_IF_MCONT_EOB);
> else
> - pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB);
> + pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB);
>
> - pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num);
> spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> }
>
> @@ -471,10 +417,10 @@ static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv,
> unsigned long flags;
>
> spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num);
> + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, buffer_num);
>
> - if (ioread32(&priv->regs->if1_mcont) & PCH_IF_MCONT_EOB)
> + if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB)
> *link = PCH_DISABLE;
> else
> *link = PCH_ENABLE;
> @@ -486,37 +432,37 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv)
> int i;
>
> for (i = 0; i < PCH_RX_OBJ_NUM; i++) {
> - iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if1_cmask);
> - iowrite32(0xffff, &priv->regs->if1_mask1);
> - iowrite32(0xffff, &priv->regs->if1_mask2);
> - iowrite32(0x0, &priv->regs->if1_id1);
> - iowrite32(0x0, &priv->regs->if1_id2);
> - iowrite32(0x0, &priv->regs->if1_mcont);
> - iowrite32(0x0, &priv->regs->if1_dataa1);
> - iowrite32(0x0, &priv->regs->if1_dataa2);
> - iowrite32(0x0, &priv->regs->if1_datab1);
> - iowrite32(0x0, &priv->regs->if1_datab2);
> + iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[0].cmask);
> + iowrite32(0xffff, &priv->regs->ifregs[0].mask1);
> + iowrite32(0xffff, &priv->regs->ifregs[0].mask2);
> + iowrite32(0x0, &priv->regs->ifregs[0].id1);
> + iowrite32(0x0, &priv->regs->ifregs[0].id2);
> + iowrite32(0x0, &priv->regs->ifregs[0].mcont);
> + iowrite32(0x0, &priv->regs->ifregs[0].dataa1);
> + iowrite32(0x0, &priv->regs->ifregs[0].dataa2);
> + iowrite32(0x0, &priv->regs->ifregs[0].datab1);
> + iowrite32(0x0, &priv->regs->ifregs[0].datab2);
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK |
> PCH_CMASK_ARB | PCH_CMASK_CTRL,
> - &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
> + &priv->regs->ifregs[0].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1);
> }
>
> for (i = i; i < PCH_OBJ_NUM; i++) {
> - iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if2_cmask);
> - iowrite32(0xffff, &priv->regs->if2_mask1);
> - iowrite32(0xffff, &priv->regs->if2_mask2);
> - iowrite32(0x0, &priv->regs->if2_id1);
> - iowrite32(0x0, &priv->regs->if2_id2);
> - iowrite32(0x0, &priv->regs->if2_mcont);
> - iowrite32(0x0, &priv->regs->if2_dataa1);
> - iowrite32(0x0, &priv->regs->if2_dataa2);
> - iowrite32(0x0, &priv->regs->if2_datab1);
> - iowrite32(0x0, &priv->regs->if2_datab2);
> + iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[1].cmask);
> + iowrite32(0xffff, &priv->regs->ifregs[1].mask1);
> + iowrite32(0xffff, &priv->regs->ifregs[1].mask2);
> + iowrite32(0x0, &priv->regs->ifregs[1].id1);
> + iowrite32(0x0, &priv->regs->ifregs[1].id2);
> + iowrite32(0x0, &priv->regs->ifregs[1].mcont);
> + iowrite32(0x0, &priv->regs->ifregs[1].dataa1);
> + iowrite32(0x0, &priv->regs->ifregs[1].dataa2);
> + iowrite32(0x0, &priv->regs->ifregs[1].datab1);
> + iowrite32(0x0, &priv->regs->ifregs[1].datab2);
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK |
> PCH_CMASK_ARB | PCH_CMASK_CTRL,
> - &priv->regs->if2_cmask);
> - pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
> + &priv->regs->ifregs[1].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1);
> }
> }
>
> @@ -530,58 +476,60 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv)
> for (i = 0; i < PCH_OBJ_NUM; i++) {
> if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) {
> iowrite32(PCH_CMASK_RX_TX_GET,
> - &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
> + &priv->regs->ifregs[0].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1);
>
> - iowrite32(0x0, &priv->regs->if1_id1);
> - iowrite32(0x0, &priv->regs->if1_id2);
> + iowrite32(0x0, &priv->regs->ifregs[0].id1);
> + iowrite32(0x0, &priv->regs->ifregs[0].id2);
>
> - pch_can_bit_set(&priv->regs->if1_mcont,
> + pch_can_bit_set(&priv->regs->ifregs[0].mcont,
> PCH_IF_MCONT_UMASK);
>
> /* Set FIFO mode set to 0 except last Rx Obj*/
> - pch_can_bit_clear(&priv->regs->if1_mcont,
> + pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
> PCH_IF_MCONT_EOB);
> /* In case FIFO mode, Last EoB of Rx Obj must be 1 */
> if (i == (PCH_RX_OBJ_NUM - 1))
> - pch_can_bit_set(&priv->regs->if1_mcont,
> + pch_can_bit_set(&priv->regs->ifregs[0].mcont,
> PCH_IF_MCONT_EOB);
>
> - iowrite32(0, &priv->regs->if1_mask1);
> - pch_can_bit_clear(&priv->regs->if1_mask2,
> + iowrite32(0, &priv->regs->ifregs[0].mask1);
> + pch_can_bit_clear(&priv->regs->ifregs[0].mask2,
> 0x1fff | PCH_MASK2_MDIR_MXTD);
>
> /* Setting CMASK for writing */
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK |
> PCH_CMASK_ARB | PCH_CMASK_CTRL,
> - &priv->regs->if1_cmask);
> + &priv->regs->ifregs[0].cmask);
>
> - pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, i+1);
> } else if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) {
> iowrite32(PCH_CMASK_RX_TX_GET,
> - &priv->regs->if2_cmask);
> - pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
> + &priv->regs->ifregs[1].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1);
>
> /* Resetting DIR bit for reception */
> - iowrite32(0x0, &priv->regs->if2_id1);
> - iowrite32(0x0, &priv->regs->if2_id2);
> - pch_can_bit_set(&priv->regs->if2_id2, PCH_ID2_DIR);
> + iowrite32(0x0, &priv->regs->ifregs[1].id1);
> + iowrite32(0x0, &priv->regs->ifregs[1].id2);
> + pch_can_bit_set(&priv->regs->ifregs[1].id2,
> + PCH_ID2_DIR);
>
> /* Setting EOB bit for transmitter */
> - iowrite32(PCH_IF_MCONT_EOB, &priv->regs->if2_mcont);
> + iowrite32(PCH_IF_MCONT_EOB,
> + &priv->regs->ifregs[1].mcont);
>
> - pch_can_bit_set(&priv->regs->if2_mcont,
> + pch_can_bit_set(&priv->regs->ifregs[1].mcont,
> PCH_IF_MCONT_UMASK);
>
> - iowrite32(0, &priv->regs->if2_mask1);
> - pch_can_bit_clear(&priv->regs->if2_mask2, 0x1fff);
> + iowrite32(0, &priv->regs->ifregs[1].mask1);
> + pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff);
>
> /* Setting CMASK for writing */
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK |
> PCH_CMASK_ARB | PCH_CMASK_CTRL,
> - &priv->regs->if2_cmask);
> + &priv->regs->ifregs[1].cmask);
>
> - pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, i+1);
> }
> }
> spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> @@ -611,10 +559,10 @@ static void pch_can_release(struct pch_can_priv *priv)
> pch_can_set_int_enables(priv, PCH_CAN_NONE);
>
> /* Disabling all the receive object. */
> - pch_can_rx_disable_all(priv);
> + pch_can_set_rx_all(priv, 0);
>
> /* Disabling all the transmit object. */
> - pch_can_tx_disable_all(priv);
> + pch_can_set_tx_all(priv, 0);
> }
>
> /* This function clears interrupt(s) from the CAN device. */
> @@ -630,31 +578,31 @@ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask)
> /* Setting CMASK for clearing interrupts for
> frame transmission. */
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB,
> - &priv->regs->if2_cmask);
> + &priv->regs->ifregs[1].cmask);
>
> /* Resetting the ID registers. */
> - pch_can_bit_set(&priv->regs->if2_id2,
> + pch_can_bit_set(&priv->regs->ifregs[1].id2,
> PCH_ID2_DIR | (0x7ff << 2));
> - iowrite32(0x0, &priv->regs->if2_id1);
> + iowrite32(0x0, &priv->regs->ifregs[1].id1);
>
> /* Claring NewDat, TxRqst & IntPnd */
> - pch_can_bit_clear(&priv->regs->if2_mcont,
> + pch_can_bit_clear(&priv->regs->ifregs[1].mcont,
> PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND |
> PCH_IF_MCONT_TXRQXT);
> - pch_can_check_if_busy(&priv->regs->if2_creq, mask);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, mask);
> } else if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_RX) {
> /* Setting CMASK for clearing the reception interrupts. */
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB,
> - &priv->regs->if1_cmask);
> + &priv->regs->ifregs[0].cmask);
>
> /* Clearing the Dir bit. */
> - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR);
> + pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR);
>
> /* Clearing NewDat & IntPnd */
> - pch_can_bit_clear(&priv->regs->if1_mcont,
> + pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
> PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND);
>
> - pch_can_check_if_busy(&priv->regs->if1_creq, mask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, mask);
> }
> }
>
> @@ -685,8 +633,8 @@ static void pch_can_error(struct net_device *ndev, u32 status)
> return;
>
> if (status & PCH_BUS_OFF) {
> - pch_can_tx_disable_all(priv);
> - pch_can_rx_disable_all(priv);
> + pch_can_set_tx_all(priv, 0);
> + pch_can_set_rx_all(priv, 0);
> state = CAN_STATE_BUS_OFF;
> cf->can_id |= CAN_ERR_BUSOFF;
> can_bus_off(ndev);
> @@ -783,22 +731,22 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat)
> struct net_device_stats *stats = &(priv->ndev->stats);
>
> /* Reading the messsage object from the Message RAM */
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, int_stat);
> + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, int_stat);
>
> /* Reading the MCONT register. */
> - reg = ioread32(&priv->regs->if1_mcont);
> + reg = ioread32(&priv->regs->ifregs[0].mcont);
> reg &= 0xffff;
>
> for (k = int_stat; !(reg & PCH_IF_MCONT_EOB); k++) {
> /* If MsgLost bit set. */
> if (reg & PCH_IF_MCONT_MSGLOST) {
> dev_err(&priv->ndev->dev, "Msg Obj is overwritten.\n");
> - pch_can_bit_clear(&priv->regs->if1_mcont,
> + pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
> PCH_IF_MCONT_MSGLOST);
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL,
> - &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, k);
> + &priv->regs->ifregs[0].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k);
>
> skb = alloc_can_err_skb(ndev, &cf);
> if (!skb)
> @@ -824,29 +772,30 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat)
> return -ENOMEM;
>
> /* Get Received data */
> - ide = ((ioread32(&priv->regs->if1_id2)) & PCH_ID2_XTD) >> 14;
> + ide = ((ioread32(&priv->regs->ifregs[0].id2)) & PCH_ID2_XTD) >>
> + 14;
> if (ide) {
> - id = (ioread32(&priv->regs->if1_id1) & 0xffff);
> - id |= (((ioread32(&priv->regs->if1_id2)) &
> + id = (ioread32(&priv->regs->ifregs[0].id1) & 0xffff);
> + id |= (((ioread32(&priv->regs->ifregs[0].id2)) &
> 0x1fff) << 16);
> cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG;
> } else {
> - id = (((ioread32(&priv->regs->if1_id2)) &
> - (CAN_SFF_MASK << 2)) >> 2);
> + id = (((ioread32(&priv->regs->ifregs[0].id2)) &
> + (CAN_SFF_MASK << 2)) >> 2);
> cf->can_id = (id & CAN_SFF_MASK);
> }
>
> - rtr = (ioread32(&priv->regs->if1_id2) & PCH_ID2_DIR);
> + rtr = (ioread32(&priv->regs->ifregs[0].id2) & PCH_ID2_DIR);
> if (rtr) {
> cf->can_dlc = 0;
> cf->can_id |= CAN_RTR_FLAG;
> } else {
> - cf->can_dlc = ((ioread32(&priv->regs->if1_mcont)) &
> - 0x0f);
> + cf->can_dlc = ((ioread32(&priv->regs->ifregs[0].mcont))
> + & 0x0f);
> }
>
> for (i = 0, j = 0; i < cf->can_dlc; j++) {
> - reg = ioread32(&priv->regs->if1_dataa1 + j*4);
> + reg = ioread32(&priv->regs->ifregs[0].dataa1 + j*4);
> cf->data[i++] = cpu_to_le32(reg & 0xff);
> if (i == cf->can_dlc)
> break;
> @@ -860,15 +809,16 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat)
>
> if (k < PCH_FIFO_THRESH) {
> iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL |
> - PCH_CMASK_ARB, &priv->regs->if1_cmask);
> + PCH_CMASK_ARB, &priv->regs->ifregs[0].cmask);
>
> /* Clearing the Dir bit. */
> - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR);
> + pch_can_bit_clear(&priv->regs->ifregs[0].id2,
> + PCH_ID2_DIR);
>
> /* Clearing NewDat & IntPnd */
> - pch_can_bit_clear(&priv->regs->if1_mcont,
> + pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
> PCH_IF_MCONT_INTPND);
> - pch_can_check_if_busy(&priv->regs->if1_creq, k);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k);
> } else if (k > PCH_FIFO_THRESH) {
> pch_can_int_clr(priv, k);
> } else if (k == PCH_FIFO_THRESH) {
> @@ -878,9 +828,9 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat)
> }
> RX_NEXT:
> /* Reading the messsage object from the Message RAM */
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask);
> - pch_can_check_if_busy(&priv->regs->if1_creq, k + 1);
> - reg = ioread32(&priv->regs->if1_mcont);
> + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[0].creq, k + 1);
> + reg = ioread32(&priv->regs->ifregs[0].mcont);
> }
>
> return rcv_pkts;
> @@ -910,8 +860,9 @@ INT_STAT:
>
> if (reg_stat & PCH_TX_OK) {
> spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
> - pch_can_check_if_busy(&priv->regs->if2_creq,
> + iowrite32(PCH_CMASK_RX_TX_GET,
> + &priv->regs->ifregs[1].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq,
> ioread32(&priv->regs->intr));
> spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> pch_can_bit_clear(&priv->regs->stat, PCH_TX_OK);
> @@ -938,10 +889,11 @@ MSG_OBJ:
> can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_NUM - 1);
> spin_lock_irqsave(&priv->msgif_reg_lock, flags);
> iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND,
> - &priv->regs->if2_cmask);
> - dlc = ioread32(&priv->regs->if2_mcont) &
> + &priv->regs->ifregs[1].cmask);
> + dlc = ioread32(&priv->regs->ifregs[1].mcont) &
> PCH_IF_MCONT_DLC;
> - pch_can_check_if_busy(&priv->regs->if2_creq, int_stat);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq,
> + int_stat);
> spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
> if (dlc > 8)
> dlc = 8;
> @@ -996,8 +948,8 @@ static void pch_can_start(struct net_device *ndev)
> pch_set_bittiming(ndev);
> pch_can_set_optmode(priv);
>
> - pch_can_tx_enable_all(priv);
> - pch_can_rx_enable_all(priv);
> + pch_can_set_tx_all(priv, 1);
> + pch_can_set_rx_all(priv, 1);
>
> /* Setting the CAN to run mode. */
> pch_can_set_run_mode(priv, PCH_CAN_RUN);
> @@ -1125,54 +1077,55 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
> spin_lock_irqsave(&priv->msgif_reg_lock, flags);
>
> /* Reading the Msg Obj from the Msg RAM to the Interface register. */
> - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask);
> - pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail);
> + iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail);
>
> /* Setting the CMASK register. */
> - pch_can_bit_set(&priv->regs->if2_cmask, PCH_CMASK_ALL);
> + pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL);
>
> /* If ID extended is set. */
> - pch_can_bit_clear(&priv->regs->if2_id1, 0xffff);
> - pch_can_bit_clear(&priv->regs->if2_id2, 0x1fff | PCH_ID2_XTD);
> + pch_can_bit_clear(&priv->regs->ifregs[1].id1, 0xffff);
> + pch_can_bit_clear(&priv->regs->ifregs[1].id2, 0x1fff | PCH_ID2_XTD);
> if (cf->can_id & CAN_EFF_FLAG) {
> - pch_can_bit_set(&priv->regs->if2_id1, cf->can_id & 0xffff);
> - pch_can_bit_set(&priv->regs->if2_id2,
> + pch_can_bit_set(&priv->regs->ifregs[1].id1,
> + cf->can_id & 0xffff);
> + pch_can_bit_set(&priv->regs->ifregs[1].id2,
> ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD);
> } else {
> - pch_can_bit_set(&priv->regs->if2_id1, 0);
> - pch_can_bit_set(&priv->regs->if2_id2,
> + pch_can_bit_set(&priv->regs->ifregs[1].id1, 0);
> + pch_can_bit_set(&priv->regs->ifregs[1].id2,
> (cf->can_id & CAN_SFF_MASK) << 2);
> }
>
> /* If remote frame has to be transmitted.. */
> if (cf->can_id & CAN_RTR_FLAG)
> - pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID2_DIR);
> + pch_can_bit_clear(&priv->regs->ifregs[1].id2, PCH_ID2_DIR);
>
> for (i = 0, j = 0; i < cf->can_dlc; j++) {
> iowrite32(le32_to_cpu(cf->data[i++]),
> - (&priv->regs->if2_dataa1) + j*4);
> + (&priv->regs->ifregs[1].dataa1) + j*4);
> if (i == cf->can_dlc)
> break;
> iowrite32(le32_to_cpu(cf->data[i++] << 8),
> - (&priv->regs->if2_dataa1) + j*4);
> + (&priv->regs->ifregs[1].dataa1) + j*4);
> }
>
> can_put_echo_skb(skb, ndev, tx_buffer_avail - PCH_RX_OBJ_NUM - 1);
>
> /* Updating the size of the data. */
> - pch_can_bit_clear(&priv->regs->if2_mcont, 0x0f);
> - pch_can_bit_set(&priv->regs->if2_mcont, cf->can_dlc);
> + pch_can_bit_clear(&priv->regs->ifregs[1].mcont, 0x0f);
> + pch_can_bit_set(&priv->regs->ifregs[1].mcont, cf->can_dlc);
>
> /* Clearing IntPend, NewDat & TxRqst */
> - pch_can_bit_clear(&priv->regs->if2_mcont,
> + pch_can_bit_clear(&priv->regs->ifregs[1].mcont,
> PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND |
> PCH_IF_MCONT_TXRQXT);
>
> /* Setting NewDat, TxRqst bits */
> - pch_can_bit_set(&priv->regs->if2_mcont,
> + pch_can_bit_set(&priv->regs->ifregs[1].mcont,
> PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT);
>
> - pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail);
> + pch_can_check_if_busy(&priv->regs->ifregs[1].creq, tx_buffer_avail);
>
> spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
>
> @@ -1234,25 +1187,25 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
> /* Save Tx buffer enable state */
> for (i = 0; i < PCH_OBJ_NUM; i++) {
> if (priv->msg_obj[i] == PCH_MSG_OBJ_TX)
> - pch_can_get_tx_enable(priv, i + 1,
> - &(priv->tx_enable[i]));
> + priv->tx_enable[i] = pch_can_get_rxtx_ir(priv, i + 1,
> + PCH_TX_IFREG);
> }
>
> /* Disable all Transmit buffers */
> - pch_can_tx_disable_all(priv);
> + pch_can_set_tx_all(priv, 0);
>
> /* Save Rx buffer enable state */
> for (i = 0; i < PCH_OBJ_NUM; i++) {
> if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) {
> - pch_can_get_rx_enable(priv, i + 1,
> - &(priv->rx_enable[i]));
> + priv->rx_enable[i] = pch_can_get_rxtx_ir(priv, i + 1,
> + PCH_RX_IFREG);
> pch_can_get_rx_buffer_link(priv, i + 1,
> &(priv->rx_link[i]));
> }
> }
>
> /* Disable all Receive buffers */
> - pch_can_rx_disable_all(priv);
> + pch_can_set_rx_all(priv, 0);
> retval = pci_save_state(pdev);
> if (retval) {
> dev_err(&pdev->dev, "pci_save_state failed.\n");
> @@ -1301,10 +1254,9 @@ static int pch_can_resume(struct pci_dev *pdev)
>
> /* Enabling the transmit buffer. */
> for (i = 0; i < PCH_OBJ_NUM; i++) {
> - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) {
> - pch_can_set_tx_enable(priv, i + 1,
> - priv->tx_enable[i]);
> - }
> + if (priv->msg_obj[i] == PCH_MSG_OBJ_TX)
> + pch_can_set_rxtx(priv, i, priv->tx_enable[i],
> + PCH_TX_IFREG);
> }
>
> /* Configuring the receive buffer and enabling them. */
> @@ -1315,7 +1267,9 @@ static int pch_can_resume(struct pci_dev *pdev)
> priv->rx_link[i]);
>
> /* Restore buffer enables */
> - pch_can_set_rx_enable(priv, i + 1, priv->rx_enable[i]);
> + pch_can_set_rxtx(priv, i, priv->rx_enable[i],
> + PCH_RX_IFREG);
> +
> }
> }
>
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
[-- Attachment #2: Type: text/plain, Size: 188 bytes --]
_______________________________________________
Socketcan-core mailing list
Socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-core
^ permalink raw reply
* [net-2.6 PATCH] be2net: Fix to avoid firmware update when interface is not open.
From: Sarveshwar Bandi @ 2010-11-19 9:44 UTC (permalink / raw)
To: netdev; +Cc: davem
Since interrupts are enabled only when open is called on the interface,
Attempting a firmware update operation when interface is down could lead to
partial success or failure of operation. This fix fails the request if
netif_running is false.
Signed-off-by: Sarveshwar Bandi <Sarveshwar.Bandi@emulex.com>
---
drivers/net/benet/be_main.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index c36cd2f..93354ee 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -2458,6 +2458,12 @@ int be_load_fw(struct be_adapter *adapte
int status, i = 0, num_imgs = 0;
const u8 *p;
+ if (!netif_running(adapter->netdev)) {
+ dev_err(&adapter->pdev->dev,
+ "Firmware load not allowed (interface is down)\n");
+ return -EPERM;
+ }
+
strcpy(fw_file, func);
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
--
1.4.0
^ permalink raw reply related
* Re: [PATCH net-next-2.6] filter: cleanup codes[] init
From: Eric Dumazet @ 2010-11-19 9:54 UTC (permalink / raw)
To: Changli Gao; +Cc: David S. Miller, Hagen Paul Pfeifer, netdev
In-Reply-To: <AANLkTikxUnj-_ov_5o6zDffv2M8J8JJg-M5HS6dr4s=a@mail.gmail.com>
Le vendredi 19 novembre 2010 à 16:38 +0800, Changli Gao a écrit :
> I compared the asm code of sk_run_filter.
> As you see, an additional 'dec %edx' instruction is inserted.
> sk_chk_filter() only runs 1 times, I think we can afford the 'dec
> instruction' and 'dirty' code, but sk_run_filter() runs much often,
> this additional dec instruction isn't affordable.
>
Maybe on your setup. By the way, the
u32 f_k = fentry->k;
that David added in commit 57fe93b374a6b871
was much more a problem on arches with not enough registers.
x86_32 for example : compiler use a register (%esi on my gcc-4.5.1) to
store f_k, and more important A register is now stored in stack instead
of a cpu register.
On my compilers
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) 64bit
gcc-4.5.1 (self compiled) 32bit
result code was the same, before and after patch
Most probably you have "CONFIG_CC_OPTIMIZE_FOR_SIZE=y" which
unfortunately is known to generate poor looking code.
39b: 49 8d 14 c6 lea (%r14,%rax,8),%rdx
39f: 66 83 3a 2d cmpw $0x2d,(%rdx)
3a3: 8b 42 04 mov 0x4(%rdx),%eax // f_k = fentry->k;
3a6: 76 28 jbe 3d0 <sk_run_filter+0x70>
3d0: 0f b7 0a movzwl (%rdx),%ecx
3d3: ff 24 cd 00 00 00 00 jmpq *0x0(,%rcx,8)
32bit code:
2e0: 8d 04 df lea (%edi,%ebx,8),%eax
2e3: 66 83 38 2d cmpw $0x2d,(%eax)
2e7: 8b 70 04 mov 0x4(%eax),%esi // f_k = fentry->k;
2ea: 76 1c jbe 308 <sk_run_filter+0x58>
308: 0f b7 10 movzwl (%eax),%edx
30b: ff 24 95 38 00 00 00 jmp *0x38(,%edx,4)
DIV_X instruction :
480: 8b 45 a4 mov -0x5c(%ebp),%eax
483: 85 c0 test %eax,%eax
485: 0f 84 9d fe ff ff je 328 <sk_run_filter+0x78>
48b: 8b 45 ac mov -0x54(%ebp),%eax // A
48e: 31 d2 xor %edx,%edx
490: f7 75 a4 divl -0x5c(%ebp)
493: 89 45 ac mov %eax,-0x54(%ebp) // A
496: e9 85 fe ff ff jmp 320 <sk_run_filter+0x70>
I believe we should revert the u32 f_k = fentry->k; part
fentry->k as is fast as f_k if stored on stack, and avoids one
instruction if fentry->k is not needed.
^ permalink raw reply
* Re: alchemy/gpr: au1000_eth regression with v2.6.37rc2
From: Wolfgang Grandegger @ 2010-11-19 10:29 UTC (permalink / raw)
To: Florian Fainelli; +Cc: Linux-MIPS, Netdev
In-Reply-To: <201011182330.08488.florian@openwrt.org>
Hello Florian,
On 11/18/2010 11:30 PM, Florian Fainelli wrote:
> Hello Wolfgang,
>
> Le Thursday 18 November 2010 20:59:15, Wolfgang Grandegger a écrit :
>> Hello,
>>
>> I just realized that the v2.6.37-rc2 kernel does not boot any more on
>> the Alchemy GPR board. It works fine with v2.6.36. It hangs in the
>> probe function of the au1000_eth driver when probing the second
>> ethernet port (eth1):
>>
>> au1000_eth_mii: probed
>> au1000-eth au1000-eth.0: (unregistered net_device): attached PHY driver
>> [Generic PHY] (mii_bus:phy_addr=0:00, irq=-1) au1000-eth au1000-eth.0:
>> eth0: Au1xx0 Ethernet found at 0x10500000, irq 35 au1000_eth: au1000_eth
>> version 1.7 Pete Popov <ppopov@embeddedalley.com> ... hangs ...
>>
>> Similar messages should follow for eth1. I narrowed down (bisect'ed) the
>> problem to commit:
>>
>> commit d0e7cb5d401695809ba8c980124ab1d8c66efc8b
>> Author: Florian Fainelli <florian@openwrt.org>
>> Date: Wed Sep 8 11:15:13 2010 +0000
>>
>> au1000-eth: remove volatiles, switch to I/O accessors
>>
>> Remove all the volatile keywords where they were used, switch to using
>> the proper readl/writel accessors.
>>
>> Signed-off-by: Florian Fainelli <florian@openwrt.org>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>>
>> The kernel actually hangs when accessing "&aup->mac->mii_control" in
>> au1000_mdio_read(), but only for eth1. Any idea what does go wrong?
>
> I do not understand so far while it hangs only for eth1. My device only has
> one ethernet MAC, so I could not notice the problem. Looking at this close,
> there are a couple of u32 const* usages in au1000_mdio_{read,write} which are
> looking wrong to me now. Can you try to remove these?
That did not help.
>> In principle, I do not want to access the MII regs of the MAC because
>> eth0 and eth1 are connected to switches. But that's not possible, even
>> with "aup->phy_static_config=1" and "aup->phy_addr=0".
>
> If you think this is another issue, I will fix it in another patch.
Accessing the MII registers of the MAC should not hang the system even
if I do not need to. First I want to understand why. Looks like a wired
optimizer issue.
BTW: why do you use readl() and writel() instead of the usual au_readl()
and au_writel() to access memory mapped cpu registers? It did not help,
anyway.
Wolfgang
^ permalink raw reply
* Re: alchemy/gpr: au1000_eth regression with v2.6.37rc2
From: Florian Fainelli @ 2010-11-19 10:46 UTC (permalink / raw)
To: Wolfgang Grandegger; +Cc: Linux-MIPS, Netdev
In-Reply-To: <4CE65199.7030007@grandegger.com>
Hello Wolfgang,
On Friday 19 November 2010 11:29:45 Wolfgang Grandegger wrote:
> Hello Florian,
>
> On 11/18/2010 11:30 PM, Florian Fainelli wrote:
> > Hello Wolfgang,
> >
> > Le Thursday 18 November 2010 20:59:15, Wolfgang Grandegger a écrit :
> >> Hello,
> >>
> >> I just realized that the v2.6.37-rc2 kernel does not boot any more on
> >> the Alchemy GPR board. It works fine with v2.6.36. It hangs in the
> >> probe function of the au1000_eth driver when probing the second
> >>
> >> ethernet port (eth1):
> >> au1000_eth_mii: probed
> >> au1000-eth au1000-eth.0: (unregistered net_device): attached PHY
> >> driver
> >>
> >> [Generic PHY] (mii_bus:phy_addr=0:00, irq=-1) au1000-eth au1000-eth.0:
> >> eth0: Au1xx0 Ethernet found at 0x10500000, irq 35 au1000_eth: au1000_eth
> >> version 1.7 Pete Popov <ppopov@embeddedalley.com> ... hangs ...
> >>
> >> Similar messages should follow for eth1. I narrowed down (bisect'ed) the
> >>
> >> problem to commit:
> >> commit d0e7cb5d401695809ba8c980124ab1d8c66efc8b
> >> Author: Florian Fainelli <florian@openwrt.org>
> >> Date: Wed Sep 8 11:15:13 2010 +0000
> >>
> >> au1000-eth: remove volatiles, switch to I/O accessors
> >>
> >> Remove all the volatile keywords where they were used, switch to
> >> using
> >>
> >> the proper readl/writel accessors.
> >>
> >> Signed-off-by: Florian Fainelli <florian@openwrt.org>
> >> Signed-off-by: David S. Miller <davem@davemloft.net>
> >>
> >> The kernel actually hangs when accessing "&aup->mac->mii_control" in
> >> au1000_mdio_read(), but only for eth1. Any idea what does go wrong?
> >
> > I do not understand so far while it hangs only for eth1. My device only
> > has one ethernet MAC, so I could not notice the problem. Looking at this
> > close, there are a couple of u32 const* usages in
> > au1000_mdio_{read,write} which are looking wrong to me now. Can you try
> > to remove these?
>
> That did not help.
I suspected it, but thanks for the confirmation.
>
> >> In principle, I do not want to access the MII regs of the MAC because
> >> eth0 and eth1 are connected to switches. But that's not possible, even
> >> with "aup->phy_static_config=1" and "aup->phy_addr=0".
> >
> > If you think this is another issue, I will fix it in another patch.
>
> Accessing the MII registers of the MAC should not hang the system even
> if I do not need to. First I want to understand why. Looks like a wired
> optimizer issue.
I definitively agree, furthermore since there is a timeout for read and write
operations. I will look at the assembly and see if I can see anything
different.
>
> BTW: why do you use readl() and writel() instead of the usual au_readl()
> and au_writel() to access memory mapped cpu registers? It did not help,
> anyway.
This is just because they are generic accessors, and the au_{readl,writel}
variants were not different.
--
Florian
^ permalink raw reply
* Re: [RFC PATCH] netfilter: remove the duplicate tables
From: Jan Engelhardt @ 2010-11-19 11:15 UTC (permalink / raw)
To: Eric Dumazet
Cc: Changli Gao, Patrick McHardy, David S. Miller, netfilter-devel,
netdev
In-Reply-To: <1290095020.2781.203.camel@edumazet-laptop>
On Thursday 2010-11-18 16:43, Eric Dumazet wrote:
>Le jeudi 18 novembre 2010 à 22:39 +0800, Changli Gao a écrit :
>> As only xt_counters are private to each CPU, we don't need to maintain
>> a whole individual table for each CPU.
>>
>> In the kernel space, we use the memory of ipt_entry.counters to save a
>> pointer to a percpu xt_counters. When iptables runs, it only update the
>> counters on its own CPU.
>>
>> On non SMP platforms, no change is made.
>>
>> Only the code of iptables is converted. Thanks for reviews.
>>
>
>Changli
>
>I answered you a (difficult) work was in progress
Was it? Quoting Patrick from 24h prior to this post:
|so patches to get rid of the table duplication are highly welcome.
>still you post a patch that needs our review and time ? This is crazy.
You do not need to do it, but I will happily look at this.
Of course my observations are the same as yours:
>Your way of allocating a percpu counter for each counter is a pure TLB
>and cache line blower (up to two cache lines per counter), not counting
>the time needed to load a new table with 10.000 entries. Some people
>still use scripts with hundred of calls to iptables.
The two are statistically independent though. Even for a loaded
ruleset, the TLB/DC miss accumulation will be desastrous - as I've found
with linked-list rules/small allocs.
>Allocating one contiguous percpu var for all counters is a must.
>
>Problem is : percpu alloc doesnt allow big allocations.
>
>#define PCPU_MIN_UNIT_SIZE PFN_ALIGN(32 << 10)
>
>So max allocation is 32 Kbytes, thats 2048 'xt_counters' only.
>-> cannot really use pcpu-alloc, but a kmalloc_node() or vmalloc_node()
>per cpu
.. as is already done for jumpstack ;-)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next-2.6] filter: optimize sk_run_filter
From: Eric Dumazet @ 2010-11-19 11:17 UTC (permalink / raw)
To: David Miller; +Cc: Hagen Paul Pfeifer, netdev, Changli Gao
In-Reply-To: <1290160467.3034.33.camel@edumazet-laptop>
Le vendredi 19 novembre 2010 à 10:54 +0100, Eric Dumazet a écrit :
> I believe we should revert the u32 f_k = fentry->k; part
>
> fentry->k as is fast as f_k if stored on stack, and avoids one
> instruction if fentry->k is not needed.
>
>
A revert is not good on arches with decent number of registers (x86_64
for example).
Maybe have some CONFIG_ARCH_HAS_{FEW|MANY}_REGISTERS is needed, (or
already exist ?)
Here is the patch to save 400 bytes on x86_32, and really speedup the
damn thing on all arches.
Thanks
[PATCH net-next-2.6] filter: optimize sk_run_filter
remove pc variable to avoid arithmetic to compute fentry at each filter
instruction. Jumps directly manipulate fentry pointer.
As the last instruction of filter[] is guaranteed to be a RETURN, and
all jumps are before the last instruction, we dont need to check filter
bounds (number of instructions in filter array) at each iteration, so we
remove it from sk_run_filter() params.
On x86_32 remove f_k var introduced in commit 57fe93b374a6b871
(filter: make sure filters dont read uninitialized memory)
Note : We could use a CONFIG_ARCH_HAS_{FEW|MANY}_REGISTERS in order to
avoid too many ifdefs in this code.
This helps compiler to use cpu registers to hold fentry and A
accumulator.
On x86_32, this saves 401 bytes, and more important, sk_run_filter()
runs much faster because less register pressure (One less conditional
branch per BPF instruction)
# size net/core/filter.o net/core/filter_pre.o
text data bss dec hex filename
2948 0 0 2948 b84 net/core/filter.o
3349 0 0 3349 d15 net/core/filter_pre.o
on x86_64 :
# size net/core/filter.o net/core/filter_pre.o
text data bss dec hex filename
5173 0 0 5173 1435 net/core/filter.o
5224 0 0 5224 1468 net/core/filter_pre.o
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Changli Gao <xiaosuo@gmail.com>
Cc: Hagen Paul Pfeifer <hagen@jauu.net>
---
include/linux/filter.h | 2
net/core/filter.c | 93 +++++++++++++++++++-------------------
net/core/timestamping.c | 2
net/packet/af_packet.c | 2
4 files changed, 51 insertions(+), 48 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 151f5d7..447a775 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -147,7 +147,7 @@ struct sock;
extern int sk_filter(struct sock *sk, struct sk_buff *skb);
extern unsigned int sk_run_filter(struct sk_buff *skb,
- struct sock_filter *filter, int flen);
+ const struct sock_filter *filter);
extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
extern int sk_detach_filter(struct sock *sk);
extern int sk_chk_filter(struct sock_filter *filter, int flen);
diff --git a/net/core/filter.c b/net/core/filter.c
index 15a545d..9e77b3c 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -137,7 +137,7 @@ int sk_filter(struct sock *sk, struct sk_buff *skb)
rcu_read_lock_bh();
filter = rcu_dereference_bh(sk->sk_filter);
if (filter) {
- unsigned int pkt_len = sk_run_filter(skb, filter->insns, filter->len);
+ unsigned int pkt_len = sk_run_filter(skb, filter->insns);
err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM;
}
@@ -151,14 +151,15 @@ EXPORT_SYMBOL(sk_filter);
* sk_run_filter - run a filter on a socket
* @skb: buffer to run the filter on
* @filter: filter to apply
- * @flen: length of filter
*
* Decode and apply filter instructions to the skb->data.
- * Return length to keep, 0 for none. skb is the data we are
- * filtering, filter is the array of filter instructions, and
- * len is the number of filter blocks in the array.
+ * Return length to keep, 0 for none. @skb is the data we are
+ * filtering, @filter is the array of filter instructions.
+ * Because all jumps are guaranteed to be before last instruction,
+ * and last instruction guaranteed to be a RET, we dont need to check
+ * flen. (We used to pass to this function the length of filter)
*/
-unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
+unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry)
{
void *ptr;
u32 A = 0; /* Accumulator */
@@ -167,34 +168,36 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
unsigned long memvalid = 0;
u32 tmp;
int k;
- int pc;
BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG);
/*
* Process array of filter instructions.
*/
- for (pc = 0; pc < flen; pc++) {
- const struct sock_filter *fentry = &filter[pc];
- u32 f_k = fentry->k;
+ for (;; fentry++) {
+#if defined(CONFIG_X86_32)
+#define K (fentry->k)
+#else
+ const u32 K = fentry->k;
+#endif
switch (fentry->code) {
case BPF_S_ALU_ADD_X:
A += X;
continue;
case BPF_S_ALU_ADD_K:
- A += f_k;
+ A += K;
continue;
case BPF_S_ALU_SUB_X:
A -= X;
continue;
case BPF_S_ALU_SUB_K:
- A -= f_k;
+ A -= K;
continue;
case BPF_S_ALU_MUL_X:
A *= X;
continue;
case BPF_S_ALU_MUL_K:
- A *= f_k;
+ A *= K;
continue;
case BPF_S_ALU_DIV_X:
if (X == 0)
@@ -202,64 +205,64 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
A /= X;
continue;
case BPF_S_ALU_DIV_K:
- A /= f_k;
+ A /= K;
continue;
case BPF_S_ALU_AND_X:
A &= X;
continue;
case BPF_S_ALU_AND_K:
- A &= f_k;
+ A &= K;
continue;
case BPF_S_ALU_OR_X:
A |= X;
continue;
case BPF_S_ALU_OR_K:
- A |= f_k;
+ A |= K;
continue;
case BPF_S_ALU_LSH_X:
A <<= X;
continue;
case BPF_S_ALU_LSH_K:
- A <<= f_k;
+ A <<= K;
continue;
case BPF_S_ALU_RSH_X:
A >>= X;
continue;
case BPF_S_ALU_RSH_K:
- A >>= f_k;
+ A >>= K;
continue;
case BPF_S_ALU_NEG:
A = -A;
continue;
case BPF_S_JMP_JA:
- pc += f_k;
+ fentry += K;
continue;
case BPF_S_JMP_JGT_K:
- pc += (A > f_k) ? fentry->jt : fentry->jf;
+ fentry += (A > K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JGE_K:
- pc += (A >= f_k) ? fentry->jt : fentry->jf;
+ fentry += (A >= K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JEQ_K:
- pc += (A == f_k) ? fentry->jt : fentry->jf;
+ fentry += (A == K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JSET_K:
- pc += (A & f_k) ? fentry->jt : fentry->jf;
+ fentry += (A & K) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JGT_X:
- pc += (A > X) ? fentry->jt : fentry->jf;
+ fentry += (A > X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JGE_X:
- pc += (A >= X) ? fentry->jt : fentry->jf;
+ fentry += (A >= X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JEQ_X:
- pc += (A == X) ? fentry->jt : fentry->jf;
+ fentry += (A == X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_JMP_JSET_X:
- pc += (A & X) ? fentry->jt : fentry->jf;
+ fentry += (A & X) ? fentry->jt : fentry->jf;
continue;
case BPF_S_LD_W_ABS:
- k = f_k;
+ k = K;
load_w:
ptr = load_pointer(skb, k, 4, &tmp);
if (ptr != NULL) {
@@ -268,7 +271,7 @@ load_w:
}
break;
case BPF_S_LD_H_ABS:
- k = f_k;
+ k = K;
load_h:
ptr = load_pointer(skb, k, 2, &tmp);
if (ptr != NULL) {
@@ -277,7 +280,7 @@ load_h:
}
break;
case BPF_S_LD_B_ABS:
- k = f_k;
+ k = K;
load_b:
ptr = load_pointer(skb, k, 1, &tmp);
if (ptr != NULL) {
@@ -292,34 +295,34 @@ load_b:
X = skb->len;
continue;
case BPF_S_LD_W_IND:
- k = X + f_k;
+ k = X + K;
goto load_w;
case BPF_S_LD_H_IND:
- k = X + f_k;
+ k = X + K;
goto load_h;
case BPF_S_LD_B_IND:
- k = X + f_k;
+ k = X + K;
goto load_b;
case BPF_S_LDX_B_MSH:
- ptr = load_pointer(skb, f_k, 1, &tmp);
+ ptr = load_pointer(skb, K, 1, &tmp);
if (ptr != NULL) {
X = (*(u8 *)ptr & 0xf) << 2;
continue;
}
return 0;
case BPF_S_LD_IMM:
- A = f_k;
+ A = K;
continue;
case BPF_S_LDX_IMM:
- X = f_k;
+ X = K;
continue;
case BPF_S_LD_MEM:
- A = (memvalid & (1UL << f_k)) ?
- mem[f_k] : 0;
+ A = (memvalid & (1UL << K)) ?
+ mem[K] : 0;
continue;
case BPF_S_LDX_MEM:
- X = (memvalid & (1UL << f_k)) ?
- mem[f_k] : 0;
+ X = (memvalid & (1UL << K)) ?
+ mem[K] : 0;
continue;
case BPF_S_MISC_TAX:
X = A;
@@ -328,16 +331,16 @@ load_b:
A = X;
continue;
case BPF_S_RET_K:
- return f_k;
+ return K;
case BPF_S_RET_A:
return A;
case BPF_S_ST:
- memvalid |= 1UL << f_k;
- mem[f_k] = A;
+ memvalid |= 1UL << K;
+ mem[K] = A;
continue;
case BPF_S_STX:
- memvalid |= 1UL << f_k;
- mem[f_k] = X;
+ memvalid |= 1UL << K;
+ mem[K] = X;
continue;
default:
WARN_ON(1);
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 0ae6c22..dac7ed6 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -31,7 +31,7 @@ static unsigned int classify(struct sk_buff *skb)
if (likely(skb->dev &&
skb->dev->phydev &&
skb->dev->phydev->drv))
- return sk_run_filter(skb, ptp_filter, ARRAY_SIZE(ptp_filter));
+ return sk_run_filter(skb, ptp_filter);
else
return PTP_CLASS_NONE;
}
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2096456..b6372dd 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -519,7 +519,7 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
rcu_read_lock_bh();
filter = rcu_dereference_bh(sk->sk_filter);
if (filter != NULL)
- res = sk_run_filter(skb, filter->insns, filter->len);
+ res = sk_run_filter(skb, filter->insns);
rcu_read_unlock_bh();
return res;
^ permalink raw reply related
* Re: [RFC PATCH] netfilter: remove the duplicate tables
From: Eric Dumazet @ 2010-11-19 11:29 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Changli Gao, Patrick McHardy, David S. Miller, netfilter-devel,
netdev, Stephen Hemminger
In-Reply-To: <alpine.LNX.2.01.1011191210290.29394@obet.zrqbmnf.qr>
Le vendredi 19 novembre 2010 à 12:15 +0100, Jan Engelhardt a écrit :
> Was it? Quoting Patrick from 24h prior to this post:
>
> |so patches to get rid of the table duplication are highly welcome.
>
> >still you post a patch that needs our review and time ? This is crazy.
>
> You do not need to do it, but I will happily look at this.
> Of course my observations are the same as yours:
>
> >Your way of allocating a percpu counter for each counter is a pure TLB
> >and cache line blower (up to two cache lines per counter), not counting
> >the time needed to load a new table with 10.000 entries. Some people
> >still use scripts with hundred of calls to iptables.
>
> The two are statistically independent though. Even for a loaded
> ruleset, the TLB/DC miss accumulation will be desastrous - as I've found
> with linked-list rules/small allocs.
>
> >Allocating one contiguous percpu var for all counters is a must.
> >
> >Problem is : percpu alloc doesnt allow big allocations.
> >
> >#define PCPU_MIN_UNIT_SIZE PFN_ALIGN(32 << 10)
> >
> >So max allocation is 32 Kbytes, thats 2048 'xt_counters' only.
> >-> cannot really use pcpu-alloc, but a kmalloc_node() or vmalloc_node()
> >per cpu
>
> .. as is already done for jumpstack ;-)
IMHO, the real problem is not the table duplication. We know that adding
a level of indirection is going to hurt a lot because of cache misses.
Its the atomic op (spinlock) done for every packet, entering every
filter, with the conditional branch we do because of possible recursion.
per cpu variable, and spinlock... its really expensive.
Stephen tried an RCU conversion some time ago, that aborted because of
RCU drawbacks (too much memory was possibly waiting to be freed after a
grace period). Maybe RCU infrastructure is now ready to try again.
We should do what we did for u64 stats counters in network stack, using
the u64_stats_sync.h infrastructure. No more synchro between the threads
running through rules, and one gathering counters. Better latencies in
particular.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next-2.6] filter: cleanup codes[] init
From: Changli Gao @ 2010-11-19 12:21 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, Hagen Paul Pfeifer, netdev
In-Reply-To: <1290160467.3034.33.camel@edumazet-laptop>
On Fri, Nov 19, 2010 at 5:54 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> Most probably you have "CONFIG_CC_OPTIMIZE_FOR_SIZE=y" which
> unfortunately is known to generate poor looking code.
Yes. So
Acked-by: Changli Gao <xiaosuo@gmail.com>
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* Re: [PATCH net-next-2.6] filter: optimize sk_run_filter
From: Changli Gao @ 2010-11-19 12:32 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, Hagen Paul Pfeifer, netdev
In-Reply-To: <1290165472.3034.109.camel@edumazet-laptop>
On Fri, Nov 19, 2010 at 7:17 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le vendredi 19 novembre 2010 à 10:54 +0100, Eric Dumazet a écrit :
>
>> I believe we should revert the u32 f_k = fentry->k; part
>>
>> fentry->k as is fast as f_k if stored on stack, and avoids one
>> instruction if fentry->k is not needed.
>>
>>
>
> A revert is not good on arches with decent number of registers (x86_64
> for example).
>
> Maybe have some CONFIG_ARCH_HAS_{FEW|MANY}_REGISTERS is needed, (or
> already exist ?)
>
> Here is the patch to save 400 bytes on x86_32, and really speedup the
> damn thing on all arches.
>
> Thanks
>
> [PATCH net-next-2.6] filter: optimize sk_run_filter
>
> remove pc variable to avoid arithmetic to compute fentry at each filter
> instruction. Jumps directly manipulate fentry pointer.
>
> As the last instruction of filter[] is guaranteed to be a RETURN, and
> all jumps are before the last instruction, we dont need to check filter
> bounds (number of instructions in filter array) at each iteration, so we
> remove it from sk_run_filter() params.
>
> On x86_32 remove f_k var introduced in commit 57fe93b374a6b871
> (filter: make sure filters dont read uninitialized memory)
>
> Note : We could use a CONFIG_ARCH_HAS_{FEW|MANY}_REGISTERS in order to
> avoid too many ifdefs in this code.
>
> This helps compiler to use cpu registers to hold fentry and A
> accumulator.
>
> On x86_32, this saves 401 bytes, and more important, sk_run_filter()
> runs much faster because less register pressure (One less conditional
> branch per BPF instruction)
>
> # size net/core/filter.o net/core/filter_pre.o
> text data bss dec hex filename
> 2948 0 0 2948 b84 net/core/filter.o
> 3349 0 0 3349 d15 net/core/filter_pre.o
>
> on x86_64 :
> # size net/core/filter.o net/core/filter_pre.o
> text data bss dec hex filename
> 5173 0 0 5173 1435 net/core/filter.o
> 5224 0 0 5224 1468 net/core/filter_pre.o
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Changli Gao <xiaosuo@gmail.com>
> Cc: Hagen Paul Pfeifer <hagen@jauu.net>
> ---
> include/linux/filter.h | 2
> net/core/filter.c | 93 +++++++++++++++++++-------------------
> net/core/timestamping.c | 2
> net/packet/af_packet.c | 2
> 4 files changed, 51 insertions(+), 48 deletions(-)
>
you missed the users of sk_run_filter in directory dev/.
--
Regards,
Changli Gao(xiaosuo@gmail.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