* Re: netem and hierarchical ingress traffic shaping
From: Stephen Hemminger @ 2011-12-18 19:55 UTC (permalink / raw)
To: John A. Sullivan III; +Cc: netdev
In-Reply-To: <1324185132.8451.439.camel@denise.theartistscloset.com>
On Sun, 18 Dec 2011 00:12:12 -0500
"John A. Sullivan III" <jsullivan@opensourcedevel.com> wrote:
> Since netem appears to be classless, we realized we would need to
> replace the SFQ on each leaf with netem which we really didn't want to
> do - not only to not lose SFQ but because we didn't want to maintain the
> netem parameters on each leaf. So, we activated our ifb1 interface,
> placed netem on it and redirected all the egress traffic to ifb1. Taht
> worked fine.
Current versions of netem can take one class.
^ permalink raw reply
* [PATCH] davinci-cpdma: fix locking issue in cpdma_chan_stop
From: Ilya Yanok @ 2011-12-18 20:02 UTC (permalink / raw)
To: netdev, linux-omap; +Cc: Ilya Yanok
Free the channel lock before calling __cpdma_chan_process to prevent
dead lock.
Signed-off-by: Ilya Yanok <yanok@emcraft.com>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index dca9d33..c97d2f5 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -836,11 +836,13 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
chan_write(chan, cp, CPDMA_TEARDOWN_VALUE);
/* handle completed packets */
+ spin_unlock_irqrestore(&chan->lock, flags);
do {
ret = __cpdma_chan_process(chan);
if (ret < 0)
break;
} while ((ret & CPDMA_DESC_TD_COMPLETE) == 0);
+ spin_lock_irqsave(&chan->lock, flags);
/* remaining packets haven't been tx/rx'ed, clean them up */
while (chan->head) {
--
1.7.6.4
^ permalink raw reply related
* Re: [PATCH] davinci-cpdma: fix locking issue in cpdma_chan_stop
From: Palande, Ameya @ 2011-12-18 23:45 UTC (permalink / raw)
To: Ilya Yanok; +Cc: netdev, linux-omap
In-Reply-To: <1324238524-21330-1-git-send-email-yanok@emcraft.com>
Tested-by: Ameya Palande <2ameya@gmail.com>
On Sun, Dec 18, 2011 at 12:02 PM, Ilya Yanok <yanok@emcraft.com> wrote:
> Free the channel lock before calling __cpdma_chan_process to prevent
> dead lock.
>
> Signed-off-by: Ilya Yanok <yanok@emcraft.com>
> ---
> drivers/net/ethernet/ti/davinci_cpdma.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
> index dca9d33..c97d2f5 100644
> --- a/drivers/net/ethernet/ti/davinci_cpdma.c
> +++ b/drivers/net/ethernet/ti/davinci_cpdma.c
> @@ -836,11 +836,13 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
> chan_write(chan, cp, CPDMA_TEARDOWN_VALUE);
>
> /* handle completed packets */
> + spin_unlock_irqrestore(&chan->lock, flags);
> do {
> ret = __cpdma_chan_process(chan);
> if (ret < 0)
> break;
> } while ((ret & CPDMA_DESC_TD_COMPLETE) == 0);
> + spin_lock_irqsave(&chan->lock, flags);
>
> /* remaining packets haven't been tx/rx'ed, clean them up */
> while (chan->head) {
> --
> 1.7.6.4
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" 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] ARM: net: JIT compiler for packet filters
From: Mircea Gherzan @ 2011-12-18 23:48 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: mgherzan, netdev
Based of Matt Evans's PPC64 implementation.
Supports only ARM mode with EABI.
Supports both little and big endian. Depends on the support for
unaligned loads on ARMv7. Does not support all the BPF opcodes
that deal with ancillary data. The scratch memory of the filter
lives on the stack.
Enabled in the same way as for x86-64 and PPC64:
echo 1 > /proc/sys/net/core/bpf_jit_enable
A value greater than 1 enables opcode output.
Signed-off-by: Mircea Gherzan <mgherzan@gmail.com>
---
arch/arm/Kconfig | 1 +
arch/arm/Makefile | 1 +
arch/arm/net/Makefile | 3 +
arch/arm/net/bpf_jit_32.c | 840 +++++++++++++++++++++++++++++++++++++++++++++
arch/arm/net/bpf_jit_32.h | 174 ++++++++++
5 files changed, 1019 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/net/Makefile
create mode 100644 arch/arm/net/bpf_jit_32.c
create mode 100644 arch/arm/net/bpf_jit_32.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index abba5b8..ea65c41 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -30,6 +30,7 @@ config ARM
select HAVE_SPARSE_IRQ
select GENERIC_IRQ_SHOW
select CPU_PM if (SUSPEND || CPU_IDLE)
+ select HAVE_BPF_JIT if (!THUMB2_KERNEL && AEABI)
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index dfcf3b0..8810a10 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -255,6 +255,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y += arch/arm/net/
core-y += $(machdirs) $(platdirs)
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile
new file mode 100644
index 0000000..c2c1084
--- /dev/null
+++ b/arch/arm/net/Makefile
@@ -0,0 +1,3 @@
+# ARM-specific networking code
+
+obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
new file mode 100644
index 0000000..4d4c2a0
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.c
@@ -0,0 +1,840 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/compiler.h>
+#include <linux/filter.h>
+#include <linux/moduleloader.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+
+#include "bpf_jit_32.h"
+
+/*
+ * ABI:
+ *
+ * r0 scratch register
+ * r4 BPF register A
+ * r5 BPF register X
+ * r6 pointer to the skb
+ * r7 skb->data
+ * r8 skb_headlen(skb)
+ */
+
+#define r_scratch ARM_R0
+/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */
+#define r_off ARM_R1
+#define r_A ARM_R4
+#define r_X ARM_R5
+#define r_skb ARM_R6
+#define r_skb_data ARM_R7
+#define r_skb_hl ARM_R8
+
+#define SCRATCH_SP_OFFSET 0
+#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k))
+
+#define SEEN_MEM 0xff
+#define SEEN_MEM_WORD(k) (1 << (k))
+#define SEEN_X (1 << 16)
+#define SEEN_CALL (1 << 17)
+#define SEEN_DATA (1 << 18)
+#define SEEN_LEN (1 << 19)
+
+struct jit_ctx {
+ const struct sk_filter *skf;
+ unsigned idx;
+ unsigned prologue_bytes;
+ int ret0_fp_idx;
+ u32 seen;
+ u32 *offsets;
+ u32 *target;
+#if __LINUX_ARM_ARCH__ < 7
+ u16 epilogue_bytes;
+ u16 imm_count;
+ u32 *imms;
+#endif
+};
+
+int bpf_jit_enable __read_mostly;
+
+static u8 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
+{
+ u8 ret;
+ skb_copy_bits(skb, offset, &ret, 1);
+ return ret;
+}
+
+static u16 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
+{
+ u16 ret;
+ skb_copy_bits(skb, offset, &ret, 2);
+ return ntohs(ret);
+}
+
+static u32 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
+{
+ u32 ret;
+ skb_copy_bits(skb, offset, &ret, 4);
+ return ntohl(ret);
+}
+
+static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
+{
+ if (ctx->target != NULL)
+ ctx->target[ctx->idx] = inst | (cond << 28);
+
+ ctx->idx++;
+}
+
+/*
+ * Emit an instruction that will be executed unconditionally.
+ */
+static inline void emit(u32 inst, struct jit_ctx *ctx)
+{
+ _emit(ARM_COND_AL, inst, ctx);
+}
+
+static u16 saved_regs(struct jit_ctx *ctx)
+{
+ u16 ret = 0;
+
+ if (ctx->skf->len > 1)
+ ret |= 1 << r_A;
+
+#ifdef CONFIG_FRAME_POINTER
+ ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC);
+#else
+ if (ctx->seen & SEEN_CALL)
+ ret |= 1 << ARM_LR;
+#endif
+ if (ctx->seen & (SEEN_DATA | SEEN_LEN))
+ ret |= 1 << r_skb;
+ if (ctx->seen & SEEN_DATA)
+ ret |= (1 << r_skb_data) | (1 << r_skb_hl);
+ if (ctx->seen & SEEN_X)
+ ret |= 1 << r_X;
+
+ return ret;
+}
+
+static inline int mem_words_used(struct jit_ctx *ctx)
+{
+ u32 words = ctx->seen & SEEN_MEM;
+ /* yes, we do waste some stack space IF there are "holes" in the set" */
+ return (words) ? 16 - __builtin_clz(words) : 0;
+}
+
+static inline bool is_load_to_a(u16 inst)
+{
+ switch (inst) {
+ case BPF_S_LD_W_LEN:
+ case BPF_S_LD_W_ABS:
+ case BPF_S_LD_H_ABS:
+ case BPF_S_LD_B_ABS:
+ case BPF_S_ANC_CPU:
+ case BPF_S_ANC_IFINDEX:
+ case BPF_S_ANC_MARK:
+ case BPF_S_ANC_PROTOCOL:
+ case BPF_S_ANC_RXHASH:
+ case BPF_S_ANC_QUEUE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void build_prologue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+ u16 first_inst = ctx->skf->insns[0].code;
+ u16 off;
+
+#ifdef CONFIG_FRAME_POINTER
+ emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx);
+ emit(ARM_PUSH(reg_set), ctx);
+ emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx);
+#else
+ if (reg_set)
+ emit(ARM_PUSH(reg_set), ctx);
+#endif
+
+ if (ctx->seen & (SEEN_DATA | SEEN_LEN))
+ emit(ARM_MOV_R(r_skb, ARM_R0), ctx);
+
+ if (ctx->seen & SEEN_DATA) {
+ off = offsetof(struct sk_buff, data);
+ emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx);
+ /* headlen = len - data_len */
+ off = offsetof(struct sk_buff, len);
+ emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx);
+ off = offsetof(struct sk_buff, data_len);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+ emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx);
+ }
+
+ if (ctx->seen & SEEN_X)
+ emit(ARM_MOV_I(r_X, 0), ctx);
+
+ /* do not leak kernel data to userspace */
+ if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst)))
+ emit(ARM_MOV_I(r_A, 0), ctx);
+
+ /* stack space for the BPF_MEM words */
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+}
+
+static void build_epilogue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+
+ reg_set &= ~(1 << ARM_LR);
+
+#ifdef CONFIG_FRAME_POINTER
+ /* the first instruction of the prologue was: mov ip, sp */
+ reg_set &= ~(1 << ARM_IP);
+ reg_set |= (1 << ARM_SP);
+ emit(ARM_LDM(ARM_SP, reg_set), ctx);
+#else
+ if (ctx->seen)
+ emit(ARM_POP(reg_set | (1 << ARM_PC)), ctx);
+ else
+ emit(ARM_BX(ARM_LR), ctx);
+#endif
+}
+
+static int16_t imm8m(u32 x)
+{
+ u32 rot;
+
+ for (rot = 0; rot < 16; rot++)
+ if ((x & ~ror32(0xff, 2 * rot)) == 0)
+ return rol32(x, 2 * rot) | (rot << 8);
+
+ return -1;
+}
+
+#if __LINUX_ARM_ARCH__ < 7
+static u16 imm_offset(u32 k, struct jit_ctx *ctx)
+{
+ unsigned i = 0, offset;
+ u16 imm;
+
+ /* on the "fake" run we just count them (duplicates included) */
+ if (ctx->target == NULL) {
+ ctx->imm_count++;
+ return 0;
+ }
+
+ while ((i < ctx->imm_count) && ctx->imms[i]) {
+ if (ctx->imms[i] == k)
+ break;
+ i++;
+ }
+
+ if (ctx->imms[i] == 0)
+ ctx->imms[i] = k;
+
+ /* constants go just after the epilogue */
+ offset = ctx->offsets[ctx->skf->len];
+ offset += ctx->prologue_bytes;
+ offset += ctx->epilogue_bytes;
+ offset += i * 4;
+
+ ctx->target[offset / 4] = k;
+
+ /* PC in ARM mode == address of the instruction + 8 */
+ imm = offset - (8 + ctx->idx * 4);
+
+ return imm;
+}
+#endif /* __LINUX_ARM_ARCH__ */
+
+
+/*
+ * Move an immediate that's not an imm8m to a core register.
+ */
+static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx)
+{
+#if __LINUX_ARM_ARCH__ >= 7
+ emit(ARM_MOVW(rd, val & 0xffff), ctx);
+ if (val > 0xffff)
+ emit(ARM_MOVT(rd, val >> 16), ctx);
+#else
+ emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx);
+#endif
+}
+
+static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx)
+{
+ int imm12 = imm8m(val);
+
+ if (imm12 >= 0)
+ emit(ARM_MOV_I(rd, imm12), ctx);
+ else
+ emit_mov_i_no8m(rd, val, ctx);
+}
+
+#if __LINUX_ARM_ARCH__ < 7
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx);
+ _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx);
+ _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx);
+ _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx);
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx);
+}
+
+
+#else /* ARMv7 */
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV(r_res, r_res), ctx);
+#endif
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV16(r_res, r_res), ctx);
+#endif
+}
+
+
+#endif /* __LINUX_ARM_ARCH__ < 6 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx)
+{
+ emit(ARM_LSL_R(ARM_R1, r_src, 8), ctx);
+ emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSL, 8), ctx);
+ emit(ARM_LSL_I(r_dst, r_dst, 8), ctx);
+ emit(ARM_LSL_R(r_dst, r_dst, 8), ctx);
+}
+
+#else /* ARMv6 or ARMv7 */
+
+static inline void emit_swap16(u8 r_dst __maybe_unused,
+ u8 r_src __maybe_unused,
+ struct jit_ctx *ctx __maybe_unused)
+{
+#ifdef __LITTLE_ENDIAN
+ emit(ARM_REV16(r_dst, r_src), ctx);
+#endif
+}
+
+#endif /* __LINUX_ARM_ARCH__ < 6 */
+
+
+/* Compute the immediate value for a PC-relative branch. */
+static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx)
+{
+ u32 imm;
+
+ if (ctx->target == NULL)
+ return 0;
+ /*
+ * BPF allows only forward jumps and the offset of the target is
+ * still the one computed during the first pass.
+ */
+ imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8);
+
+ return imm >> 2;
+}
+
+#define OP_IMM3(op, r1, r2, imm_val, ctx) \
+ do { \
+ imm12 = imm8m(imm_val); \
+ if (imm12 < 0) { \
+ emit_mov_i_no8m(r_scratch, imm_val, ctx); \
+ emit(op ## _R((r1), (r2), r_scratch), ctx); \
+ } else { \
+ emit(op ## _I((r1), (r2), imm12), ctx); \
+ } \
+ } while (0)
+
+static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx)
+{
+ if (ctx->ret0_fp_idx >= 0) {
+ _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx);
+ /* NOP to keep the size constant between passes */
+ emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx);
+ } else {
+ _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx);
+ _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx);
+ }
+}
+
+static int build_body(struct jit_ctx *ctx)
+{
+ void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
+ const struct sk_filter *prog = ctx->skf;
+ const struct sock_filter *inst;
+ unsigned i, load_order, off, condt, condf;
+ int imm12;
+ u32 k;
+
+ for (i = 0; i < prog->len; i++) {
+ inst = &(prog->insns[i]);
+ /* K as an immediate value operand */
+ k = inst->k;
+
+ /* compute offsets only in the fake pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ switch (inst->code) {
+ case BPF_S_LD_IMM:
+ emit_mov_i(r_A, k, ctx);
+ break;
+ case BPF_S_LD_W_LEN:
+ ctx->seen |= SEEN_LEN;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+ emit(ARM_LDR_I(r_A, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_S_LD_MEM:
+ /* A = scratch[k] */
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_LD_W_ABS:
+ load_order = 2;
+ goto load;
+ case BPF_S_LD_H_ABS:
+ load_order = 1;
+ goto load;
+ case BPF_S_LD_B_ABS:
+ load_order = 0;
+load:
+ emit_mov_i(r_off, k, ctx);
+load_common:
+ ctx->seen |= SEEN_DATA | SEEN_CALL;
+
+ if (load_order > 0) {
+ emit(ARM_SUB_I(r_scratch, r_skb_hl,
+ 1 << load_order), ctx);
+ emit(ARM_CMP_R(r_scratch, r_off), ctx);
+ condt = ARM_COND_HS;
+ } else {
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+ condt = ARM_COND_HI;
+ }
+
+ _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
+ ctx);
+
+ if (load_order == 0)
+ _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0),
+ ctx);
+ else if (load_order == 1)
+ emit_load_be16(condt, r_A, r_scratch, ctx);
+ else if (load_order == 2)
+ emit_load_be32(condt, r_A, r_scratch, ctx);
+
+ _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx);
+
+ /* the slowpath */
+ emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx);
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* the offset is already in R1 */
+ emit(ARM_BLX_R(ARM_R3), ctx);
+ emit(ARM_MOV_R(r_A, ARM_R0), ctx);
+ break;
+ case BPF_S_LD_W_IND:
+ load_order = 2;
+ goto load_ind;
+ case BPF_S_LD_H_IND:
+ load_order = 1;
+ goto load_ind;
+ case BPF_S_LD_B_IND:
+ load_order = 0;
+load_ind:
+ OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
+ goto load_common;
+ case BPF_S_LDX_IMM:
+ ctx->seen |= SEEN_X;
+ emit_mov_i(r_X, k, ctx);
+ break;
+ case BPF_S_LDX_W_LEN:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LDR_I(r_X, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_S_LDX_MEM:
+ ctx->seen |= SEEN_X | SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_LDX_B_MSH:
+ /* x = ((*(frame + k)) & 0xf) << 2; */
+ ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
+ /* offset in r1: we might have to take the slow path */
+ emit_mov_i(r_off, k, ctx);
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+
+ /* load in r0: common with the slowpath */
+ _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data,
+ ARM_R1), ctx);
+ _emit(ARM_COND_HI, ARM_B((3 * 4 - 8) >> 2), ctx);
+
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* r_off is r1 */
+ emit(ARM_MOV_I(ARM_R3, (u32)jit_get_skb_b), ctx);
+ emit(ARM_BLX_R(ARM_R3), ctx);
+
+ emit(ARM_ORR_I(r_X, ARM_R0, 0x00f), ctx);
+ emit(ARM_LSL_I(r_X, r_X, 2), ctx);
+ break;
+ case BPF_S_ST:
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_STX:
+ ctx->seen |= SEEN_MEM_WORD(k) | SEEN_X;
+ emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_ALU_ADD_K:
+ /* A += K */
+ OP_IMM3(ARM_ADD, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_ADD_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_ADD_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_SUB_K:
+ /* A -= K */
+ OP_IMM3(ARM_SUB, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_SUB_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_SUB_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_MUL_K:
+ /* A *= K */
+ emit_mov_i(r_scratch, k, ctx);
+ emit(ARM_MUL(r_A, r_A, r_scratch), ctx);
+ break;
+ case BPF_S_ALU_MUL_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_MUL(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_DIV_K:
+ /* K is not zero, it was previously checked */
+ emit_mov_i(ARM_R1, k, ctx);
+ goto div;
+ case BPF_S_ALU_DIV_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_CMP_I(r_X, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+ emit(ARM_MOV_R(ARM_R1, r_X), ctx);
+div:
+ ctx->seen |= SEEN_CALL;
+
+ emit(ARM_MOV_R(ARM_R0, r_A), ctx);
+ emit_mov_i(r_scratch, (u32)__aeabi_uidiv, ctx);
+ emit(ARM_BLX_R(r_scratch), ctx);
+ emit(ARM_MOV_R(r_A, ARM_R0), ctx);
+ break;
+ case BPF_S_ALU_OR_K:
+ /* A |= K */
+ OP_IMM3(ARM_ORR, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_OR_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_ORR_I(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_AND_K:
+ /* A &= K */
+ OP_IMM3(ARM_AND, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_AND_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_AND_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_LSH_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSL_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_S_ALU_LSH_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LSL_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_RSH_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSR_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_S_ALU_RSH_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LSR_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_JMP_JA:
+ /* pc += K */
+ emit(ARM_B(b_imm(i + k, ctx)), ctx);
+ break;
+ case BPF_S_JMP_JEQ_K:
+ /* pc += (A == K) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ condf = ARM_COND_NE;
+ goto cmp_imm;
+ case BPF_S_JMP_JGT_K:
+ /* pc += (A > K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ goto cmp_imm;
+ case BPF_S_JMP_JGE_K:
+ /* pc += (A >= K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ /* (x >= y) IFF (x > y - 1) */
+ if (unlikely(k == 0))
+ return -1;
+ k--;
+cmp_imm:
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_CMP_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_CMP_I(r_A, imm12), ctx);
+ }
+cond_jump:
+ if (inst->jt)
+ _emit(condt, ARM_B(b_imm(i + inst->jt + 1,
+ ctx)), ctx);
+ if (inst->jf)
+ _emit(condf, ARM_B(b_imm(i + inst->jf + 1,
+ ctx)), ctx);
+ break;
+ case BPF_S_JMP_JEQ_X:
+ /* pc += (A == X) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ condf = ARM_COND_NE;
+ goto cmp_x;
+ case BPF_S_JMP_JGT_X:
+ /* pc += (A > X) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ goto cmp_x;
+ case BPF_S_JMP_JGE_X:
+ /* pc += (A >= X) ? pc->jt : pc->jf */
+ condt = ARM_COND_CS;
+ condf = ARM_COND_CC;
+cmp_x:
+ ctx->seen |= SEEN_X;
+ emit(ARM_CMP_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_S_JMP_JSET_K:
+ /* pc += (A & K) ? pc->jt : pc->jf */
+ condt = ARM_COND_NE;
+ /* not set iff all zeroes iff Z==1 iff EQ */
+ condf = ARM_COND_EQ;
+
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_TST_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_TST_I(r_A, imm12), ctx);
+ }
+ goto cond_jump;
+ case BPF_S_JMP_JSET_X:
+ /* pc += (A & X) ? pc->jt : pc->jf */
+ condt = ARM_COND_NE;
+ condf = ARM_COND_EQ;
+ emit(ARM_TST_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_S_RET_A:
+ emit(ARM_MOV_R(ARM_R0, r_A), ctx);
+ goto b_epilogue;
+ case BPF_S_RET_K:
+ if ((k == 0) && (ctx->ret0_fp_idx < 0))
+ ctx->ret0_fp_idx = i;
+ emit_mov_i(ARM_R0, k, ctx);
+b_epilogue:
+ if (i != ctx->skf->len - 1)
+ emit(ARM_B(b_imm(prog->len, ctx)), ctx);
+ break;
+ case BPF_S_MISC_TAX:
+ /* X = A */
+ emit(ARM_MOV_R(r_X, r_A), ctx);
+ break;
+ case BPF_S_MISC_TXA:
+ /* A = X */
+ emit(ARM_MOV_R(r_A, r_X), ctx);
+ break;
+ case BPF_S_ANC_PROTOCOL:
+ /* A = ntohs(skb->protocol) */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ protocol) != 2);
+ off = offsetof(struct sk_buff, protocol);
+ emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx);
+ emit_swap16(r_A, r_scratch, ctx);
+ break;
+ case BPF_S_ANC_CPU:
+ /* A = current_thread_info()->cpu */
+ emit_mov_i(r_scratch, (~(THREAD_SIZE - 1)), ctx);
+ emit(ARM_ADD_R(r_scratch, ARM_SP, r_scratch), ctx);
+
+ BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4);
+ off = offsetof(struct thread_info, cpu);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_S_ANC_IFINDEX:
+ /* A = skb->dev->ifindex */
+ off = offsetof(struct sk_buff, dev);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+
+ emit(ARM_CMP_I(r_scratch, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+
+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
+ ifindex) != 4);
+ off = offsetof(struct net_device, ifindex);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_S_ANC_MARK:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+ off = offsetof(struct sk_buff, mark);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_S_ANC_RXHASH:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
+ off = offsetof(struct sk_buff, rxhash);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_S_ANC_QUEUE:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ queue_mapping) != 2);
+ BUILD_BUG_ON(offsetof(struct sk_buff,
+ queue_mapping) > 0xff);
+ off = offsetof(struct sk_buff, queue_mapping);
+ emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ /* compute offsets only during the first pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ return 0;
+}
+
+
+void bpf_jit_compile(struct sk_filter *fp)
+{
+ struct jit_ctx ctx;
+ unsigned tmp_idx;
+ unsigned alloc_size;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.skf = fp;
+ ctx.ret0_fp_idx = -1;
+
+ ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1));
+ if (ctx.offsets == NULL)
+ return;
+
+ /* fake pass to fill in the ctx->seen */
+ if (unlikely(build_body(&ctx)))
+ goto out;
+
+ tmp_idx = ctx.idx;
+ build_prologue(&ctx);
+ ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4;
+
+#if __LINUX_ARM_ARCH__ < 7
+ tmp_idx = ctx.idx;
+ build_epilogue(&ctx);
+ ctx.epilogue_bytes = (ctx.idx - tmp_idx) * 4;
+
+ ctx.idx += ctx.imm_count;
+ if (ctx.imm_count) {
+ ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count);
+ if (ctx.imms == NULL)
+ goto out;
+ }
+#else
+ /* there's nothing after the epilogue on ARMv7 */
+ build_epilogue(&ctx);
+#endif
+
+ alloc_size = 4 * ctx.idx;
+ ctx.target = module_alloc(alloc_size > sizeof(struct work_struct) ?
+ alloc_size : sizeof(struct work_struct));
+ if (unlikely(ctx.target == NULL))
+ goto out;
+
+ ctx.idx = 0;
+ build_prologue(&ctx);
+ build_body(&ctx);
+ build_epilogue(&ctx);
+
+ flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
+
+#if __LINUX_ARM_ARCH__ < 7
+ if (ctx.imm_count)
+ kfree(ctx.imms);
+#endif
+
+ if (bpf_jit_enable > 1)
+ print_hex_dump(KERN_INFO, "BPF JIT code: ",
+ DUMP_PREFIX_ADDRESS, 16, 4, ctx.target,
+ alloc_size, false);
+
+ fp->bpf_func = (void *)ctx.target;
+
+out:
+ kfree(ctx.offsets);
+ return;
+}
+
+static void bpf_jit_free_worker(struct work_struct *work)
+{
+ module_free(NULL, work);
+}
+
+void bpf_jit_free(struct sk_filter *fp)
+{
+ struct work_struct *work;
+
+ if (fp->bpf_func != sk_run_filter) {
+ work = (struct work_struct *)fp->bpf_func;
+
+ INIT_WORK(work, bpf_jit_free_worker);
+ schedule_work(work);
+ }
+}
+
diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h
new file mode 100644
index 0000000..de68a51
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.h
@@ -0,0 +1,174 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#ifndef PFILTER_OPCODES_ARM_H
+#define PFILTER_OPCODES_ARM_H
+
+extern void *__aeabi_uidiv;
+
+#define ARM_R0 0
+#define ARM_R1 1
+#define ARM_R2 2
+#define ARM_R3 3
+#define ARM_R4 4
+#define ARM_R5 5
+#define ARM_R6 6
+#define ARM_R7 7
+#define ARM_R8 8
+#define ARM_R9 9
+#define ARM_R10 10
+#define ARM_FP 11
+#define ARM_IP 12
+#define ARM_SP 13
+#define ARM_LR 14
+#define ARM_PC 15
+
+#define ARM_COND_EQ 0x0
+#define ARM_COND_NE 0x1
+#define ARM_COND_CS 0x2
+#define ARM_COND_HS ARM_COND_CS
+#define ARM_COND_CC 0x3
+#define ARM_COND_LO ARM_COND_CC
+#define ARM_COND_MI 0x4
+#define ARM_COND_PL 0x5
+#define ARM_COND_VS 0x6
+#define ARM_COND_VC 0x7
+#define ARM_COND_HI 0x8
+#define ARM_COND_LS 0x9
+#define ARM_COND_GE 0xa
+#define ARM_COND_LT 0xb
+#define ARM_COND_GT 0xc
+#define ARM_COND_LE 0xd
+#define ARM_COND_AL 0xe
+
+/* register shift types */
+#define SRTYPE_LSL 0
+#define SRTYPE_LSR 1
+#define SRTYPE_ASR 2
+#define SRTYPE_ROR 3
+
+#define ARM_INST_ADD_R 0x00800000
+#define ARM_INST_ADD_I 0x02800000
+
+#define ARM_INST_AND_R 0x00000000
+#define ARM_INST_AND_I 0x02000000
+
+#define ARM_INST_B 0x0a000000
+#define ARM_INST_BX 0x012FFF10
+#define ARM_INST_BLX_R 0x012fff30
+
+#define ARM_INST_CMP_R 0x01500000
+#define ARM_INST_CMP_I 0x03500000
+
+#define ARM_INST_LDRB_I 0x05d00000
+#define ARM_INST_LDRB_R 0x07d00000
+#define ARM_INST_LDRH_I 0x01d000b0
+#define ARM_INST_LDR_I 0x05900000
+
+#define ARM_INST_LDM 0x08900000
+
+#define ARM_INST_LSL_I 0x01a00000
+#define ARM_INST_LSL_R 0x01a00010
+
+#define ARM_INST_LSR_I 0x01a00020
+#define ARM_INST_LSR_R 0x01a00030
+
+#define ARM_INST_MOV_R 0x01a00000
+#define ARM_INST_MOV_I 0x03a00000
+#define ARM_INST_MOVW 0x03000000
+#define ARM_INST_MOVT 0x03400000
+
+#define ARM_INST_MUL 0x00000090
+
+#define ARM_INST_POP 0x08bd0000
+#define ARM_INST_PUSH 0x092d0000
+
+#define ARM_INST_REV 0x06bf0f30
+#define ARM_INST_REV16 0x06bf0fb0
+
+#define ARM_INST_ORR_R 0x01800000
+#define ARM_INST_ORR_I 0x03800000
+
+#define ARM_INST_SUB_R 0x00400000
+#define ARM_INST_SUB_I 0x02400000
+
+#define ARM_INST_STR_I 0x05800000
+
+#define ARM_INST_TST_R 0x01100000
+#define ARM_INST_TST_I 0x03100000
+
+
+/* register */
+#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm))
+/* immediate */
+#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm))
+
+#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm)
+#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm)
+
+#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm)
+#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm)
+
+#define ARM_B(imm24) (ARM_INST_B | (imm24))
+#define ARM_BX(rm) (ARM_INST_BX | (rm))
+#define ARM_BLX_R(rm) (ARM_INST_BLX_R | (rm))
+
+#define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm)
+#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm)
+
+#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \
+ | (rm))
+#define ARM_LDRH_I(rt, rn, off) (ARM_INST_LDRH_I | (rt) << 12 | (rn) << 16 \
+ | (((off) & 0xf0) << 4) | ((off) & 0xf))
+
+#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs))
+
+#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8)
+#define ARM_LSL_I(rd, rn, imm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (imm) << 7)
+
+#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8)
+#define ARM_LSR_I(rd, rn, imm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (imm) << 7)
+
+#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm)
+#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm)
+
+#define ARM_MOVW(rd, imm) \
+ (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MOVT(rd, imm) \
+ (ARM_INST_MOVT | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MUL(rd, rm, rn) (ARM_INST_MUL | (rd) << 16 | (rm) << 8 | (rn))
+
+#define ARM_POP(regs) (ARM_INST_POP | (regs))
+#define ARM_PUSH(regs) (ARM_INST_PUSH | (regs))
+
+#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm)
+#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm)
+#define ARM_ORR_S(rd, rn, rm, type, rs) \
+ (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7)
+
+#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm))
+#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm))
+
+#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm)
+#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm)
+
+#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+
+#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm)
+#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm)
+
+#endif /* PFILTER_OPCODES_ARM_H */
--
1.7.7.3
^ permalink raw reply related
* [PATCH] ARM: net: JIT compiler for packet filters
From: Mircea Gherzan @ 2011-12-18 23:49 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: mgherzan, netdev
Based of Matt Evans's PPC64 implementation.
Supports only ARM mode with EABI.
Supports both little and big endian. Depends on the support for
unaligned loads on ARMv7. Does not support all the BPF opcodes
that deal with ancillary data. The scratch memory of the filter
lives on the stack.
Enabled in the same way as for x86-64 and PPC64:
echo 1 > /proc/sys/net/core/bpf_jit_enable
A value greater than 1 enables opcode output.
Signed-off-by: Mircea Gherzan <mgherzan@gmail.com>
---
arch/arm/Kconfig | 1 +
arch/arm/Makefile | 1 +
arch/arm/net/Makefile | 3 +
arch/arm/net/bpf_jit_32.c | 840 +++++++++++++++++++++++++++++++++++++++++++++
arch/arm/net/bpf_jit_32.h | 174 ++++++++++
5 files changed, 1019 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/net/Makefile
create mode 100644 arch/arm/net/bpf_jit_32.c
create mode 100644 arch/arm/net/bpf_jit_32.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index abba5b8..ea65c41 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -30,6 +30,7 @@ config ARM
select HAVE_SPARSE_IRQ
select GENERIC_IRQ_SHOW
select CPU_PM if (SUSPEND || CPU_IDLE)
+ select HAVE_BPF_JIT if (!THUMB2_KERNEL && AEABI)
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index dfcf3b0..8810a10 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -255,6 +255,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y += arch/arm/net/
core-y += $(machdirs) $(platdirs)
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile
new file mode 100644
index 0000000..c2c1084
--- /dev/null
+++ b/arch/arm/net/Makefile
@@ -0,0 +1,3 @@
+# ARM-specific networking code
+
+obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
new file mode 100644
index 0000000..4d4c2a0
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.c
@@ -0,0 +1,840 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/compiler.h>
+#include <linux/filter.h>
+#include <linux/moduleloader.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+
+#include "bpf_jit_32.h"
+
+/*
+ * ABI:
+ *
+ * r0 scratch register
+ * r4 BPF register A
+ * r5 BPF register X
+ * r6 pointer to the skb
+ * r7 skb->data
+ * r8 skb_headlen(skb)
+ */
+
+#define r_scratch ARM_R0
+/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */
+#define r_off ARM_R1
+#define r_A ARM_R4
+#define r_X ARM_R5
+#define r_skb ARM_R6
+#define r_skb_data ARM_R7
+#define r_skb_hl ARM_R8
+
+#define SCRATCH_SP_OFFSET 0
+#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k))
+
+#define SEEN_MEM 0xff
+#define SEEN_MEM_WORD(k) (1 << (k))
+#define SEEN_X (1 << 16)
+#define SEEN_CALL (1 << 17)
+#define SEEN_DATA (1 << 18)
+#define SEEN_LEN (1 << 19)
+
+struct jit_ctx {
+ const struct sk_filter *skf;
+ unsigned idx;
+ unsigned prologue_bytes;
+ int ret0_fp_idx;
+ u32 seen;
+ u32 *offsets;
+ u32 *target;
+#if __LINUX_ARM_ARCH__ < 7
+ u16 epilogue_bytes;
+ u16 imm_count;
+ u32 *imms;
+#endif
+};
+
+int bpf_jit_enable __read_mostly;
+
+static u8 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
+{
+ u8 ret;
+ skb_copy_bits(skb, offset, &ret, 1);
+ return ret;
+}
+
+static u16 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
+{
+ u16 ret;
+ skb_copy_bits(skb, offset, &ret, 2);
+ return ntohs(ret);
+}
+
+static u32 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
+{
+ u32 ret;
+ skb_copy_bits(skb, offset, &ret, 4);
+ return ntohl(ret);
+}
+
+static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
+{
+ if (ctx->target != NULL)
+ ctx->target[ctx->idx] = inst | (cond << 28);
+
+ ctx->idx++;
+}
+
+/*
+ * Emit an instruction that will be executed unconditionally.
+ */
+static inline void emit(u32 inst, struct jit_ctx *ctx)
+{
+ _emit(ARM_COND_AL, inst, ctx);
+}
+
+static u16 saved_regs(struct jit_ctx *ctx)
+{
+ u16 ret = 0;
+
+ if (ctx->skf->len > 1)
+ ret |= 1 << r_A;
+
+#ifdef CONFIG_FRAME_POINTER
+ ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC);
+#else
+ if (ctx->seen & SEEN_CALL)
+ ret |= 1 << ARM_LR;
+#endif
+ if (ctx->seen & (SEEN_DATA | SEEN_LEN))
+ ret |= 1 << r_skb;
+ if (ctx->seen & SEEN_DATA)
+ ret |= (1 << r_skb_data) | (1 << r_skb_hl);
+ if (ctx->seen & SEEN_X)
+ ret |= 1 << r_X;
+
+ return ret;
+}
+
+static inline int mem_words_used(struct jit_ctx *ctx)
+{
+ u32 words = ctx->seen & SEEN_MEM;
+ /* yes, we do waste some stack space IF there are "holes" in the set" */
+ return (words) ? 16 - __builtin_clz(words) : 0;
+}
+
+static inline bool is_load_to_a(u16 inst)
+{
+ switch (inst) {
+ case BPF_S_LD_W_LEN:
+ case BPF_S_LD_W_ABS:
+ case BPF_S_LD_H_ABS:
+ case BPF_S_LD_B_ABS:
+ case BPF_S_ANC_CPU:
+ case BPF_S_ANC_IFINDEX:
+ case BPF_S_ANC_MARK:
+ case BPF_S_ANC_PROTOCOL:
+ case BPF_S_ANC_RXHASH:
+ case BPF_S_ANC_QUEUE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void build_prologue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+ u16 first_inst = ctx->skf->insns[0].code;
+ u16 off;
+
+#ifdef CONFIG_FRAME_POINTER
+ emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx);
+ emit(ARM_PUSH(reg_set), ctx);
+ emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx);
+#else
+ if (reg_set)
+ emit(ARM_PUSH(reg_set), ctx);
+#endif
+
+ if (ctx->seen & (SEEN_DATA | SEEN_LEN))
+ emit(ARM_MOV_R(r_skb, ARM_R0), ctx);
+
+ if (ctx->seen & SEEN_DATA) {
+ off = offsetof(struct sk_buff, data);
+ emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx);
+ /* headlen = len - data_len */
+ off = offsetof(struct sk_buff, len);
+ emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx);
+ off = offsetof(struct sk_buff, data_len);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+ emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx);
+ }
+
+ if (ctx->seen & SEEN_X)
+ emit(ARM_MOV_I(r_X, 0), ctx);
+
+ /* do not leak kernel data to userspace */
+ if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst)))
+ emit(ARM_MOV_I(r_A, 0), ctx);
+
+ /* stack space for the BPF_MEM words */
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+}
+
+static void build_epilogue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+
+ reg_set &= ~(1 << ARM_LR);
+
+#ifdef CONFIG_FRAME_POINTER
+ /* the first instruction of the prologue was: mov ip, sp */
+ reg_set &= ~(1 << ARM_IP);
+ reg_set |= (1 << ARM_SP);
+ emit(ARM_LDM(ARM_SP, reg_set), ctx);
+#else
+ if (ctx->seen)
+ emit(ARM_POP(reg_set | (1 << ARM_PC)), ctx);
+ else
+ emit(ARM_BX(ARM_LR), ctx);
+#endif
+}
+
+static int16_t imm8m(u32 x)
+{
+ u32 rot;
+
+ for (rot = 0; rot < 16; rot++)
+ if ((x & ~ror32(0xff, 2 * rot)) == 0)
+ return rol32(x, 2 * rot) | (rot << 8);
+
+ return -1;
+}
+
+#if __LINUX_ARM_ARCH__ < 7
+static u16 imm_offset(u32 k, struct jit_ctx *ctx)
+{
+ unsigned i = 0, offset;
+ u16 imm;
+
+ /* on the "fake" run we just count them (duplicates included) */
+ if (ctx->target == NULL) {
+ ctx->imm_count++;
+ return 0;
+ }
+
+ while ((i < ctx->imm_count) && ctx->imms[i]) {
+ if (ctx->imms[i] == k)
+ break;
+ i++;
+ }
+
+ if (ctx->imms[i] == 0)
+ ctx->imms[i] = k;
+
+ /* constants go just after the epilogue */
+ offset = ctx->offsets[ctx->skf->len];
+ offset += ctx->prologue_bytes;
+ offset += ctx->epilogue_bytes;
+ offset += i * 4;
+
+ ctx->target[offset / 4] = k;
+
+ /* PC in ARM mode == address of the instruction + 8 */
+ imm = offset - (8 + ctx->idx * 4);
+
+ return imm;
+}
+#endif /* __LINUX_ARM_ARCH__ */
+
+
+/*
+ * Move an immediate that's not an imm8m to a core register.
+ */
+static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx)
+{
+#if __LINUX_ARM_ARCH__ >= 7
+ emit(ARM_MOVW(rd, val & 0xffff), ctx);
+ if (val > 0xffff)
+ emit(ARM_MOVT(rd, val >> 16), ctx);
+#else
+ emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx);
+#endif
+}
+
+static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx)
+{
+ int imm12 = imm8m(val);
+
+ if (imm12 >= 0)
+ emit(ARM_MOV_I(rd, imm12), ctx);
+ else
+ emit_mov_i_no8m(rd, val, ctx);
+}
+
+#if __LINUX_ARM_ARCH__ < 7
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx);
+ _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx);
+ _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx);
+ _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx);
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx);
+}
+
+
+#else /* ARMv7 */
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV(r_res, r_res), ctx);
+#endif
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV16(r_res, r_res), ctx);
+#endif
+}
+
+
+#endif /* __LINUX_ARM_ARCH__ < 6 */
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx)
+{
+ emit(ARM_LSL_R(ARM_R1, r_src, 8), ctx);
+ emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSL, 8), ctx);
+ emit(ARM_LSL_I(r_dst, r_dst, 8), ctx);
+ emit(ARM_LSL_R(r_dst, r_dst, 8), ctx);
+}
+
+#else /* ARMv6 or ARMv7 */
+
+static inline void emit_swap16(u8 r_dst __maybe_unused,
+ u8 r_src __maybe_unused,
+ struct jit_ctx *ctx __maybe_unused)
+{
+#ifdef __LITTLE_ENDIAN
+ emit(ARM_REV16(r_dst, r_src), ctx);
+#endif
+}
+
+#endif /* __LINUX_ARM_ARCH__ < 6 */
+
+
+/* Compute the immediate value for a PC-relative branch. */
+static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx)
+{
+ u32 imm;
+
+ if (ctx->target == NULL)
+ return 0;
+ /*
+ * BPF allows only forward jumps and the offset of the target is
+ * still the one computed during the first pass.
+ */
+ imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8);
+
+ return imm >> 2;
+}
+
+#define OP_IMM3(op, r1, r2, imm_val, ctx) \
+ do { \
+ imm12 = imm8m(imm_val); \
+ if (imm12 < 0) { \
+ emit_mov_i_no8m(r_scratch, imm_val, ctx); \
+ emit(op ## _R((r1), (r2), r_scratch), ctx); \
+ } else { \
+ emit(op ## _I((r1), (r2), imm12), ctx); \
+ } \
+ } while (0)
+
+static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx)
+{
+ if (ctx->ret0_fp_idx >= 0) {
+ _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx);
+ /* NOP to keep the size constant between passes */
+ emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx);
+ } else {
+ _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx);
+ _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx);
+ }
+}
+
+static int build_body(struct jit_ctx *ctx)
+{
+ void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
+ const struct sk_filter *prog = ctx->skf;
+ const struct sock_filter *inst;
+ unsigned i, load_order, off, condt, condf;
+ int imm12;
+ u32 k;
+
+ for (i = 0; i < prog->len; i++) {
+ inst = &(prog->insns[i]);
+ /* K as an immediate value operand */
+ k = inst->k;
+
+ /* compute offsets only in the fake pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ switch (inst->code) {
+ case BPF_S_LD_IMM:
+ emit_mov_i(r_A, k, ctx);
+ break;
+ case BPF_S_LD_W_LEN:
+ ctx->seen |= SEEN_LEN;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+ emit(ARM_LDR_I(r_A, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_S_LD_MEM:
+ /* A = scratch[k] */
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_LD_W_ABS:
+ load_order = 2;
+ goto load;
+ case BPF_S_LD_H_ABS:
+ load_order = 1;
+ goto load;
+ case BPF_S_LD_B_ABS:
+ load_order = 0;
+load:
+ emit_mov_i(r_off, k, ctx);
+load_common:
+ ctx->seen |= SEEN_DATA | SEEN_CALL;
+
+ if (load_order > 0) {
+ emit(ARM_SUB_I(r_scratch, r_skb_hl,
+ 1 << load_order), ctx);
+ emit(ARM_CMP_R(r_scratch, r_off), ctx);
+ condt = ARM_COND_HS;
+ } else {
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+ condt = ARM_COND_HI;
+ }
+
+ _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
+ ctx);
+
+ if (load_order == 0)
+ _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0),
+ ctx);
+ else if (load_order == 1)
+ emit_load_be16(condt, r_A, r_scratch, ctx);
+ else if (load_order == 2)
+ emit_load_be32(condt, r_A, r_scratch, ctx);
+
+ _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx);
+
+ /* the slowpath */
+ emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx);
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* the offset is already in R1 */
+ emit(ARM_BLX_R(ARM_R3), ctx);
+ emit(ARM_MOV_R(r_A, ARM_R0), ctx);
+ break;
+ case BPF_S_LD_W_IND:
+ load_order = 2;
+ goto load_ind;
+ case BPF_S_LD_H_IND:
+ load_order = 1;
+ goto load_ind;
+ case BPF_S_LD_B_IND:
+ load_order = 0;
+load_ind:
+ OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
+ goto load_common;
+ case BPF_S_LDX_IMM:
+ ctx->seen |= SEEN_X;
+ emit_mov_i(r_X, k, ctx);
+ break;
+ case BPF_S_LDX_W_LEN:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LDR_I(r_X, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_S_LDX_MEM:
+ ctx->seen |= SEEN_X | SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_LDX_B_MSH:
+ /* x = ((*(frame + k)) & 0xf) << 2; */
+ ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
+ /* offset in r1: we might have to take the slow path */
+ emit_mov_i(r_off, k, ctx);
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+
+ /* load in r0: common with the slowpath */
+ _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data,
+ ARM_R1), ctx);
+ _emit(ARM_COND_HI, ARM_B((3 * 4 - 8) >> 2), ctx);
+
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* r_off is r1 */
+ emit(ARM_MOV_I(ARM_R3, (u32)jit_get_skb_b), ctx);
+ emit(ARM_BLX_R(ARM_R3), ctx);
+
+ emit(ARM_ORR_I(r_X, ARM_R0, 0x00f), ctx);
+ emit(ARM_LSL_I(r_X, r_X, 2), ctx);
+ break;
+ case BPF_S_ST:
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_STX:
+ ctx->seen |= SEEN_MEM_WORD(k) | SEEN_X;
+ emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_ALU_ADD_K:
+ /* A += K */
+ OP_IMM3(ARM_ADD, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_ADD_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_ADD_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_SUB_K:
+ /* A -= K */
+ OP_IMM3(ARM_SUB, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_SUB_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_SUB_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_MUL_K:
+ /* A *= K */
+ emit_mov_i(r_scratch, k, ctx);
+ emit(ARM_MUL(r_A, r_A, r_scratch), ctx);
+ break;
+ case BPF_S_ALU_MUL_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_MUL(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_DIV_K:
+ /* K is not zero, it was previously checked */
+ emit_mov_i(ARM_R1, k, ctx);
+ goto div;
+ case BPF_S_ALU_DIV_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_CMP_I(r_X, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+ emit(ARM_MOV_R(ARM_R1, r_X), ctx);
+div:
+ ctx->seen |= SEEN_CALL;
+
+ emit(ARM_MOV_R(ARM_R0, r_A), ctx);
+ emit_mov_i(r_scratch, (u32)__aeabi_uidiv, ctx);
+ emit(ARM_BLX_R(r_scratch), ctx);
+ emit(ARM_MOV_R(r_A, ARM_R0), ctx);
+ break;
+ case BPF_S_ALU_OR_K:
+ /* A |= K */
+ OP_IMM3(ARM_ORR, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_OR_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_ORR_I(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_AND_K:
+ /* A &= K */
+ OP_IMM3(ARM_AND, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_AND_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_AND_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_LSH_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSL_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_S_ALU_LSH_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LSL_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_RSH_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSR_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_S_ALU_RSH_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LSR_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_JMP_JA:
+ /* pc += K */
+ emit(ARM_B(b_imm(i + k, ctx)), ctx);
+ break;
+ case BPF_S_JMP_JEQ_K:
+ /* pc += (A == K) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ condf = ARM_COND_NE;
+ goto cmp_imm;
+ case BPF_S_JMP_JGT_K:
+ /* pc += (A > K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ goto cmp_imm;
+ case BPF_S_JMP_JGE_K:
+ /* pc += (A >= K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ /* (x >= y) IFF (x > y - 1) */
+ if (unlikely(k == 0))
+ return -1;
+ k--;
+cmp_imm:
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_CMP_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_CMP_I(r_A, imm12), ctx);
+ }
+cond_jump:
+ if (inst->jt)
+ _emit(condt, ARM_B(b_imm(i + inst->jt + 1,
+ ctx)), ctx);
+ if (inst->jf)
+ _emit(condf, ARM_B(b_imm(i + inst->jf + 1,
+ ctx)), ctx);
+ break;
+ case BPF_S_JMP_JEQ_X:
+ /* pc += (A == X) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ condf = ARM_COND_NE;
+ goto cmp_x;
+ case BPF_S_JMP_JGT_X:
+ /* pc += (A > X) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ goto cmp_x;
+ case BPF_S_JMP_JGE_X:
+ /* pc += (A >= X) ? pc->jt : pc->jf */
+ condt = ARM_COND_CS;
+ condf = ARM_COND_CC;
+cmp_x:
+ ctx->seen |= SEEN_X;
+ emit(ARM_CMP_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_S_JMP_JSET_K:
+ /* pc += (A & K) ? pc->jt : pc->jf */
+ condt = ARM_COND_NE;
+ /* not set iff all zeroes iff Z==1 iff EQ */
+ condf = ARM_COND_EQ;
+
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_TST_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_TST_I(r_A, imm12), ctx);
+ }
+ goto cond_jump;
+ case BPF_S_JMP_JSET_X:
+ /* pc += (A & X) ? pc->jt : pc->jf */
+ condt = ARM_COND_NE;
+ condf = ARM_COND_EQ;
+ emit(ARM_TST_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_S_RET_A:
+ emit(ARM_MOV_R(ARM_R0, r_A), ctx);
+ goto b_epilogue;
+ case BPF_S_RET_K:
+ if ((k == 0) && (ctx->ret0_fp_idx < 0))
+ ctx->ret0_fp_idx = i;
+ emit_mov_i(ARM_R0, k, ctx);
+b_epilogue:
+ if (i != ctx->skf->len - 1)
+ emit(ARM_B(b_imm(prog->len, ctx)), ctx);
+ break;
+ case BPF_S_MISC_TAX:
+ /* X = A */
+ emit(ARM_MOV_R(r_X, r_A), ctx);
+ break;
+ case BPF_S_MISC_TXA:
+ /* A = X */
+ emit(ARM_MOV_R(r_A, r_X), ctx);
+ break;
+ case BPF_S_ANC_PROTOCOL:
+ /* A = ntohs(skb->protocol) */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ protocol) != 2);
+ off = offsetof(struct sk_buff, protocol);
+ emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx);
+ emit_swap16(r_A, r_scratch, ctx);
+ break;
+ case BPF_S_ANC_CPU:
+ /* A = current_thread_info()->cpu */
+ emit_mov_i(r_scratch, (~(THREAD_SIZE - 1)), ctx);
+ emit(ARM_ADD_R(r_scratch, ARM_SP, r_scratch), ctx);
+
+ BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4);
+ off = offsetof(struct thread_info, cpu);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_S_ANC_IFINDEX:
+ /* A = skb->dev->ifindex */
+ off = offsetof(struct sk_buff, dev);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+
+ emit(ARM_CMP_I(r_scratch, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+
+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
+ ifindex) != 4);
+ off = offsetof(struct net_device, ifindex);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_S_ANC_MARK:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+ off = offsetof(struct sk_buff, mark);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_S_ANC_RXHASH:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
+ off = offsetof(struct sk_buff, rxhash);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_S_ANC_QUEUE:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ queue_mapping) != 2);
+ BUILD_BUG_ON(offsetof(struct sk_buff,
+ queue_mapping) > 0xff);
+ off = offsetof(struct sk_buff, queue_mapping);
+ emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ /* compute offsets only during the first pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ return 0;
+}
+
+
+void bpf_jit_compile(struct sk_filter *fp)
+{
+ struct jit_ctx ctx;
+ unsigned tmp_idx;
+ unsigned alloc_size;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.skf = fp;
+ ctx.ret0_fp_idx = -1;
+
+ ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1));
+ if (ctx.offsets == NULL)
+ return;
+
+ /* fake pass to fill in the ctx->seen */
+ if (unlikely(build_body(&ctx)))
+ goto out;
+
+ tmp_idx = ctx.idx;
+ build_prologue(&ctx);
+ ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4;
+
+#if __LINUX_ARM_ARCH__ < 7
+ tmp_idx = ctx.idx;
+ build_epilogue(&ctx);
+ ctx.epilogue_bytes = (ctx.idx - tmp_idx) * 4;
+
+ ctx.idx += ctx.imm_count;
+ if (ctx.imm_count) {
+ ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count);
+ if (ctx.imms == NULL)
+ goto out;
+ }
+#else
+ /* there's nothing after the epilogue on ARMv7 */
+ build_epilogue(&ctx);
+#endif
+
+ alloc_size = 4 * ctx.idx;
+ ctx.target = module_alloc(alloc_size > sizeof(struct work_struct) ?
+ alloc_size : sizeof(struct work_struct));
+ if (unlikely(ctx.target == NULL))
+ goto out;
+
+ ctx.idx = 0;
+ build_prologue(&ctx);
+ build_body(&ctx);
+ build_epilogue(&ctx);
+
+ flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
+
+#if __LINUX_ARM_ARCH__ < 7
+ if (ctx.imm_count)
+ kfree(ctx.imms);
+#endif
+
+ if (bpf_jit_enable > 1)
+ print_hex_dump(KERN_INFO, "BPF JIT code: ",
+ DUMP_PREFIX_ADDRESS, 16, 4, ctx.target,
+ alloc_size, false);
+
+ fp->bpf_func = (void *)ctx.target;
+
+out:
+ kfree(ctx.offsets);
+ return;
+}
+
+static void bpf_jit_free_worker(struct work_struct *work)
+{
+ module_free(NULL, work);
+}
+
+void bpf_jit_free(struct sk_filter *fp)
+{
+ struct work_struct *work;
+
+ if (fp->bpf_func != sk_run_filter) {
+ work = (struct work_struct *)fp->bpf_func;
+
+ INIT_WORK(work, bpf_jit_free_worker);
+ schedule_work(work);
+ }
+}
+
diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h
new file mode 100644
index 0000000..de68a51
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.h
@@ -0,0 +1,174 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#ifndef PFILTER_OPCODES_ARM_H
+#define PFILTER_OPCODES_ARM_H
+
+extern void *__aeabi_uidiv;
+
+#define ARM_R0 0
+#define ARM_R1 1
+#define ARM_R2 2
+#define ARM_R3 3
+#define ARM_R4 4
+#define ARM_R5 5
+#define ARM_R6 6
+#define ARM_R7 7
+#define ARM_R8 8
+#define ARM_R9 9
+#define ARM_R10 10
+#define ARM_FP 11
+#define ARM_IP 12
+#define ARM_SP 13
+#define ARM_LR 14
+#define ARM_PC 15
+
+#define ARM_COND_EQ 0x0
+#define ARM_COND_NE 0x1
+#define ARM_COND_CS 0x2
+#define ARM_COND_HS ARM_COND_CS
+#define ARM_COND_CC 0x3
+#define ARM_COND_LO ARM_COND_CC
+#define ARM_COND_MI 0x4
+#define ARM_COND_PL 0x5
+#define ARM_COND_VS 0x6
+#define ARM_COND_VC 0x7
+#define ARM_COND_HI 0x8
+#define ARM_COND_LS 0x9
+#define ARM_COND_GE 0xa
+#define ARM_COND_LT 0xb
+#define ARM_COND_GT 0xc
+#define ARM_COND_LE 0xd
+#define ARM_COND_AL 0xe
+
+/* register shift types */
+#define SRTYPE_LSL 0
+#define SRTYPE_LSR 1
+#define SRTYPE_ASR 2
+#define SRTYPE_ROR 3
+
+#define ARM_INST_ADD_R 0x00800000
+#define ARM_INST_ADD_I 0x02800000
+
+#define ARM_INST_AND_R 0x00000000
+#define ARM_INST_AND_I 0x02000000
+
+#define ARM_INST_B 0x0a000000
+#define ARM_INST_BX 0x012FFF10
+#define ARM_INST_BLX_R 0x012fff30
+
+#define ARM_INST_CMP_R 0x01500000
+#define ARM_INST_CMP_I 0x03500000
+
+#define ARM_INST_LDRB_I 0x05d00000
+#define ARM_INST_LDRB_R 0x07d00000
+#define ARM_INST_LDRH_I 0x01d000b0
+#define ARM_INST_LDR_I 0x05900000
+
+#define ARM_INST_LDM 0x08900000
+
+#define ARM_INST_LSL_I 0x01a00000
+#define ARM_INST_LSL_R 0x01a00010
+
+#define ARM_INST_LSR_I 0x01a00020
+#define ARM_INST_LSR_R 0x01a00030
+
+#define ARM_INST_MOV_R 0x01a00000
+#define ARM_INST_MOV_I 0x03a00000
+#define ARM_INST_MOVW 0x03000000
+#define ARM_INST_MOVT 0x03400000
+
+#define ARM_INST_MUL 0x00000090
+
+#define ARM_INST_POP 0x08bd0000
+#define ARM_INST_PUSH 0x092d0000
+
+#define ARM_INST_REV 0x06bf0f30
+#define ARM_INST_REV16 0x06bf0fb0
+
+#define ARM_INST_ORR_R 0x01800000
+#define ARM_INST_ORR_I 0x03800000
+
+#define ARM_INST_SUB_R 0x00400000
+#define ARM_INST_SUB_I 0x02400000
+
+#define ARM_INST_STR_I 0x05800000
+
+#define ARM_INST_TST_R 0x01100000
+#define ARM_INST_TST_I 0x03100000
+
+
+/* register */
+#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm))
+/* immediate */
+#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm))
+
+#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm)
+#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm)
+
+#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm)
+#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm)
+
+#define ARM_B(imm24) (ARM_INST_B | (imm24))
+#define ARM_BX(rm) (ARM_INST_BX | (rm))
+#define ARM_BLX_R(rm) (ARM_INST_BLX_R | (rm))
+
+#define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm)
+#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm)
+
+#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \
+ | (rm))
+#define ARM_LDRH_I(rt, rn, off) (ARM_INST_LDRH_I | (rt) << 12 | (rn) << 16 \
+ | (((off) & 0xf0) << 4) | ((off) & 0xf))
+
+#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs))
+
+#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8)
+#define ARM_LSL_I(rd, rn, imm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (imm) << 7)
+
+#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8)
+#define ARM_LSR_I(rd, rn, imm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (imm) << 7)
+
+#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm)
+#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm)
+
+#define ARM_MOVW(rd, imm) \
+ (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MOVT(rd, imm) \
+ (ARM_INST_MOVT | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MUL(rd, rm, rn) (ARM_INST_MUL | (rd) << 16 | (rm) << 8 | (rn))
+
+#define ARM_POP(regs) (ARM_INST_POP | (regs))
+#define ARM_PUSH(regs) (ARM_INST_PUSH | (regs))
+
+#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm)
+#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm)
+#define ARM_ORR_S(rd, rn, rm, type, rs) \
+ (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7)
+
+#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm))
+#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm))
+
+#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm)
+#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm)
+
+#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+
+#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm)
+#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm)
+
+#endif /* PFILTER_OPCODES_ARM_H */
--
1.7.7.3
^ permalink raw reply related
* Re: [PATCH net-next] igb: reset PHY after recovering from PHY power down
From: Koki Sanagi @ 2011-12-18 23:59 UTC (permalink / raw)
To: Wyborny, Carolyn
Cc: netdev@vger.kernel.org, Kirsher, Jeffrey T, Brandeburg, Jesse,
Allan, Bruce W, Skidmore, Donald C, Rose, Gregory V,
Waskiewicz Jr, Peter P, Duyck, Alexander H, Ronciak, John,
e1000-devel@lists.sourceforge.net, davem@davemloft.net
In-Reply-To: <9BBC4E0CF881AA4299206E2E1412B626C0CF@ORSMSX102.amr.corp.intel.com>
(2011/12/17 0:53), Wyborny, Carolyn wrote:
>
>
>> -----Original Message-----
>> From: Koki Sanagi [mailto:sanagi.koki@jp.fujitsu.com]
>> Sent: Wednesday, November 23, 2011 7:18 PM
>> To: netdev@vger.kernel.org; Kirsher, Jeffrey T; Brandeburg, Jesse;
>> Allan, Bruce W; Wyborny, Carolyn; Skidmore, Donald C; Rose, Gregory V;
>> Waskiewicz Jr, Peter P; Duyck, Alexander H; Ronciak, John; e1000-
>> devel@lists.sourceforge.net
>> Cc: davem@davemloft.net
>> Subject: [PATCH net-next] igb: reset PHY after recovering from PHY power
>> down
>>
>> According to 82576_Datasheet.pdf, PHY setting is lost after PHY power
>> down.
>> So resetting PHY is needed when recovering from PHY power down to set a
>> default
>> setting to PHY register.
>>
>> Owing to this lack, NIC doesn't link up in some rare situation.
>> The situation I encountered is following.
>>
>>
>> 1.Both ports connect to switch.
>> +---------+ +--------+
>> | |-----------| |
>> | 82576NS | | switch |
>> | |-----------| |
>> +---------+ +--------+
>>
>> 2.Detach both cables from switch.
>> +---------+ +--------+
>> | |------- | |
>> | 82576NS | | switch |
>> | |------- | |
>> +---------+ +--------+
>>
>> 3.Detach one cable from one port.
>> +---------+ +--------+
>> | |------- | |
>> | 82576NS | | switch |
>> | | | |
>> +---------+ +--------+
>>
>> 4.Attach that cable to the other port.(It means connecting directly each
>> port)
>> +---------+ +--------+
>> | |-------+ | |
>> | 82576NS | | | switch |
>> | |-------+ | |
>> +---------+ +--------+
>>
>> As a result, NIC doesn't link up sometimes.
>>
>> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
>> ---
>> drivers/net/ethernet/intel/igb/igb_main.c | 1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c
>> b/drivers/net/ethernet/intel/igb/igb_main.c
>> index bd9b30e..4d4f065 100644
>> --- a/drivers/net/ethernet/intel/igb/igb_main.c
>> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
>> @@ -2496,6 +2496,7 @@ static int igb_open(struct net_device *netdev)
>> goto err_setup_rx;
>>
>> igb_power_up_link(adapter);
>> + igb_reset_phy(hw);
>>
>> /* before we allocate an interrupt, we must be ready to handle it.
>> * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
>
> I apologize for the delay in getting back to you. After a review, I see
> that the needed change is simpler than I thought at first. Can you resubmit
> with the igb_reset_phy call being added to the end of the igb_power_up_link
> function instead of after it in igb_open. That way, whenever igb_power_link
> is called in the code, it will also execute the igb_reset_phy function which
> is the complete solution. Thank you for your work on the igb driver.
>
Thank you for your reply.
O.K. I'll resubmit it soon.
Thanks!
Koki Sanagi
> Carolyn
>
> Carolyn Wyborny
> Linux Development
> LAN Access Division
> Intel Corporation
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply
* [PATCH net-next v2] igb: reset PHY after recovering from PHY power down
From: Koki Sanagi @ 2011-12-19 1:24 UTC (permalink / raw)
To: netdev; +Cc: e1000-devel, bruce.w.allan, jesse.brandeburg, john.ronciak, davem
According to 82576_Datasheet.pdf, PHY setting is lost after PHY power down.
So resetting PHY is needed when recovering from PHY power down to set a default
setting to PHY register.
Owing to this lack, NIC doesn't link up in some rare situation.
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
---
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 89d576c..9b923b0 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1498,6 +1498,7 @@ void igb_power_up_link(struct igb_adapter *adapter)
igb_power_up_phy_copper(&adapter->hw);
else
igb_power_up_serdes_link_82575(&adapter->hw);
+ igb_reset_phy(&adapter->hw);
}
/**
------------------------------------------------------------------------------
Learn Windows Azure Live! Tuesday, Dec 13, 2011
Microsoft is holding a special Learn Windows Azure training event for
developers. It will provide a great way to learn Windows Azure and what it
provides. You can attend the event by watching it streamed LIVE online.
Learn more at http://p.sf.net/sfu/ms-windowsazure
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply related
* Re: [PATCH] ARM: net: JIT compiler for packet filters
From: Ben Hutchings @ 2011-12-19 2:26 UTC (permalink / raw)
To: Mircea Gherzan; +Cc: linux-arm-kernel, netdev
In-Reply-To: <1324252185-15894-1-git-send-email-mgherzan@gmail.com>
On Mon, 2011-12-19 at 00:49 +0100, Mircea Gherzan wrote:
> Based of Matt Evans's PPC64 implementation.
>
> Supports only ARM mode with EABI.
>
> Supports both little and big endian. Depends on the support for
> unaligned loads on ARMv7. Does not support all the BPF opcodes
> that deal with ancillary data. The scratch memory of the filter
> lives on the stack.
>
> Enabled in the same way as for x86-64 and PPC64:
>
> echo 1 > /proc/sys/net/core/bpf_jit_enable
>
> A value greater than 1 enables opcode output.
>
> Signed-off-by: Mircea Gherzan <mgherzan@gmail.com>
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/Makefile | 1 +
> arch/arm/net/Makefile | 3 +
> arch/arm/net/bpf_jit_32.c | 840 +++++++++++++++++++++++++++++++++++++++++++++
> arch/arm/net/bpf_jit_32.h | 174 ++++++++++
> 5 files changed, 1019 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/net/Makefile
> create mode 100644 arch/arm/net/bpf_jit_32.c
> create mode 100644 arch/arm/net/bpf_jit_32.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index abba5b8..ea65c41 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -30,6 +30,7 @@ config ARM
> select HAVE_SPARSE_IRQ
> select GENERIC_IRQ_SHOW
> select CPU_PM if (SUSPEND || CPU_IDLE)
> + select HAVE_BPF_JIT if (!THUMB2_KERNEL && AEABI)
> help
> The ARM series is a line of low-power-consumption RISC chip designs
> licensed by ARM Ltd and targeted at embedded applications and
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index dfcf3b0..8810a10 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -255,6 +255,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
>
> # If we have a machine-specific directory, then include it in the build.
> core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
> +core-y += arch/arm/net/
> core-y += $(machdirs) $(platdirs)
>
> drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
> diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile
> new file mode 100644
> index 0000000..c2c1084
> --- /dev/null
> +++ b/arch/arm/net/Makefile
> @@ -0,0 +1,3 @@
> +# ARM-specific networking code
> +
> +obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o
> diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
> new file mode 100644
> index 0000000..4d4c2a0
> --- /dev/null
> +++ b/arch/arm/net/bpf_jit_32.c
> @@ -0,0 +1,840 @@
> +/*
> + * Just-In-Time compiler for BPF filters on 32bit ARM
> + *
> + * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; version 2 of the License.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/compiler.h>
> +#include <linux/filter.h>
> +#include <linux/moduleloader.h>
> +#include <linux/netdevice.h>
> +#include <linux/string.h>
> +#include <linux/slab.h>
> +#include <asm/cacheflush.h>
> +
> +#include "bpf_jit_32.h"
> +
> +/*
> + * ABI:
> + *
> + * r0 scratch register
> + * r4 BPF register A
> + * r5 BPF register X
> + * r6 pointer to the skb
> + * r7 skb->data
> + * r8 skb_headlen(skb)
> + */
> +
> +#define r_scratch ARM_R0
> +/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */
> +#define r_off ARM_R1
> +#define r_A ARM_R4
> +#define r_X ARM_R5
> +#define r_skb ARM_R6
> +#define r_skb_data ARM_R7
> +#define r_skb_hl ARM_R8
> +
> +#define SCRATCH_SP_OFFSET 0
> +#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k))
> +
> +#define SEEN_MEM 0xff
There are 16 words of memory, so I think this should be defined as
0xffff or as (1 << BPF_MEMWORDS) - 1.
[...]
> +static inline int mem_words_used(struct jit_ctx *ctx)
> +{
> + u32 words = ctx->seen & SEEN_MEM;
> + /* yes, we do waste some stack space IF there are "holes" in the set" */
> + return (words) ? 16 - __builtin_clz(words) : 0;
> +}
[...]
Since the memory words are represented by the low bits in seen, surely
this should be:
return 32 - __builtin_clz(words);
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH] ARM: net: JIT compiler for packet filters
From: Rob Herring @ 2011-12-19 2:49 UTC (permalink / raw)
To: Mircea Gherzan; +Cc: linux-arm-kernel, netdev
In-Reply-To: <1324252185-15894-1-git-send-email-mgherzan@gmail.com>
On 12/18/2011 05:49 PM, Mircea Gherzan wrote:
> Based of Matt Evans's PPC64 implementation.
>
> Supports only ARM mode with EABI.
>
> Supports both little and big endian. Depends on the support for
> unaligned loads on ARMv7. Does not support all the BPF opcodes
> that deal with ancillary data. The scratch memory of the filter
> lives on the stack.
ARMv6 supports unaligned accesses too.
>
> Enabled in the same way as for x86-64 and PPC64:
>
> echo 1 > /proc/sys/net/core/bpf_jit_enable
>
> A value greater than 1 enables opcode output.
Any performance data for ARM?
>
> Signed-off-by: Mircea Gherzan <mgherzan@gmail.com>
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/Makefile | 1 +
> arch/arm/net/Makefile | 3 +
> arch/arm/net/bpf_jit_32.c | 840 +++++++++++++++++++++++++++++++++++++++++++++
> arch/arm/net/bpf_jit_32.h | 174 ++++++++++
> 5 files changed, 1019 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/net/Makefile
> create mode 100644 arch/arm/net/bpf_jit_32.c
> create mode 100644 arch/arm/net/bpf_jit_32.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index abba5b8..ea65c41 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -30,6 +30,7 @@ config ARM
> select HAVE_SPARSE_IRQ
> select GENERIC_IRQ_SHOW
> select CPU_PM if (SUSPEND || CPU_IDLE)
> + select HAVE_BPF_JIT if (!THUMB2_KERNEL && AEABI)
No thumb2. That's a shame...
> help
> The ARM series is a line of low-power-consumption RISC chip designs
> licensed by ARM Ltd and targeted at embedded applications and
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index dfcf3b0..8810a10 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -255,6 +255,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
>
> # If we have a machine-specific directory, then include it in the build.
> core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
> +core-y += arch/arm/net/
> core-y += $(machdirs) $(platdirs)
>
> drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
> diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile
> new file mode 100644
> index 0000000..c2c1084
> --- /dev/null
> +++ b/arch/arm/net/Makefile
> @@ -0,0 +1,3 @@
> +# ARM-specific networking code
> +
> +obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o
> diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
> new file mode 100644
> index 0000000..4d4c2a0
> --- /dev/null
> +++ b/arch/arm/net/bpf_jit_32.c
> @@ -0,0 +1,840 @@
> +/*
> + * Just-In-Time compiler for BPF filters on 32bit ARM
> + *
> + * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; version 2 of the License.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/compiler.h>
> +#include <linux/filter.h>
> +#include <linux/moduleloader.h>
> +#include <linux/netdevice.h>
> +#include <linux/string.h>
> +#include <linux/slab.h>
> +#include <asm/cacheflush.h>
> +
> +#include "bpf_jit_32.h"
> +
> +/*
> + * ABI:
> + *
> + * r0 scratch register
> + * r4 BPF register A
> + * r5 BPF register X
> + * r6 pointer to the skb
> + * r7 skb->data
> + * r8 skb_headlen(skb)
> + */
> +
> +#define r_scratch ARM_R0
> +/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */
> +#define r_off ARM_R1
> +#define r_A ARM_R4
> +#define r_X ARM_R5
> +#define r_skb ARM_R6
> +#define r_skb_data ARM_R7
> +#define r_skb_hl ARM_R8
> +
> +#define SCRATCH_SP_OFFSET 0
> +#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k))
> +
> +#define SEEN_MEM 0xff
> +#define SEEN_MEM_WORD(k) (1 << (k))
> +#define SEEN_X (1 << 16)
> +#define SEEN_CALL (1 << 17)
> +#define SEEN_DATA (1 << 18)
> +#define SEEN_LEN (1 << 19)
> +
> +struct jit_ctx {
> + const struct sk_filter *skf;
> + unsigned idx;
> + unsigned prologue_bytes;
> + int ret0_fp_idx;
> + u32 seen;
> + u32 *offsets;
> + u32 *target;
> +#if __LINUX_ARM_ARCH__ < 7
> + u16 epilogue_bytes;
> + u16 imm_count;
> + u32 *imms;
> +#endif
> +};
> +
> +int bpf_jit_enable __read_mostly;
> +
> +static u8 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
> +{
> + u8 ret;
> + skb_copy_bits(skb, offset, &ret, 1);
> + return ret;
> +}
> +
> +static u16 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
> +{
> + u16 ret;
> + skb_copy_bits(skb, offset, &ret, 2);
> + return ntohs(ret);
> +}
> +
> +static u32 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
> +{
> + u32 ret;
> + skb_copy_bits(skb, offset, &ret, 4);
> + return ntohl(ret);
> +}
> +
> +static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
> +{
> + if (ctx->target != NULL)
> + ctx->target[ctx->idx] = inst | (cond << 28);
> +
> + ctx->idx++;
> +}
> +
> +/*
> + * Emit an instruction that will be executed unconditionally.
> + */
> +static inline void emit(u32 inst, struct jit_ctx *ctx)
> +{
> + _emit(ARM_COND_AL, inst, ctx);
> +}
> +
> +static u16 saved_regs(struct jit_ctx *ctx)
> +{
> + u16 ret = 0;
> +
> + if (ctx->skf->len > 1)
> + ret |= 1 << r_A;
> +
> +#ifdef CONFIG_FRAME_POINTER
> + ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC);
> +#else
> + if (ctx->seen & SEEN_CALL)
> + ret |= 1 << ARM_LR;
> +#endif
> + if (ctx->seen & (SEEN_DATA | SEEN_LEN))
> + ret |= 1 << r_skb;
> + if (ctx->seen & SEEN_DATA)
> + ret |= (1 << r_skb_data) | (1 << r_skb_hl);
> + if (ctx->seen & SEEN_X)
> + ret |= 1 << r_X;
> +
> + return ret;
> +}
> +
> +static inline int mem_words_used(struct jit_ctx *ctx)
> +{
> + u32 words = ctx->seen & SEEN_MEM;
> + /* yes, we do waste some stack space IF there are "holes" in the set" */
> + return (words) ? 16 - __builtin_clz(words) : 0;
> +}
> +
> +static inline bool is_load_to_a(u16 inst)
> +{
> + switch (inst) {
> + case BPF_S_LD_W_LEN:
> + case BPF_S_LD_W_ABS:
> + case BPF_S_LD_H_ABS:
> + case BPF_S_LD_B_ABS:
> + case BPF_S_ANC_CPU:
> + case BPF_S_ANC_IFINDEX:
> + case BPF_S_ANC_MARK:
> + case BPF_S_ANC_PROTOCOL:
> + case BPF_S_ANC_RXHASH:
> + case BPF_S_ANC_QUEUE:
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> +static void build_prologue(struct jit_ctx *ctx)
> +{
> + u16 reg_set = saved_regs(ctx);
> + u16 first_inst = ctx->skf->insns[0].code;
> + u16 off;
> +
> +#ifdef CONFIG_FRAME_POINTER
> + emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx);
> + emit(ARM_PUSH(reg_set), ctx);
> + emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx);
> +#else
> + if (reg_set)
> + emit(ARM_PUSH(reg_set), ctx);
> +#endif
> +
> + if (ctx->seen & (SEEN_DATA | SEEN_LEN))
> + emit(ARM_MOV_R(r_skb, ARM_R0), ctx);
> +
> + if (ctx->seen & SEEN_DATA) {
> + off = offsetof(struct sk_buff, data);
> + emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx);
> + /* headlen = len - data_len */
> + off = offsetof(struct sk_buff, len);
> + emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx);
> + off = offsetof(struct sk_buff, data_len);
> + emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
> + emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx);
> + }
> +
> + if (ctx->seen & SEEN_X)
> + emit(ARM_MOV_I(r_X, 0), ctx);
> +
> + /* do not leak kernel data to userspace */
> + if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst)))
> + emit(ARM_MOV_I(r_A, 0), ctx);
> +
> + /* stack space for the BPF_MEM words */
> + if (ctx->seen & SEEN_MEM)
> + emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
> +}
> +
> +static void build_epilogue(struct jit_ctx *ctx)
> +{
> + u16 reg_set = saved_regs(ctx);
> +
> + if (ctx->seen & SEEN_MEM)
> + emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
> +
> + reg_set &= ~(1 << ARM_LR);
> +
> +#ifdef CONFIG_FRAME_POINTER
> + /* the first instruction of the prologue was: mov ip, sp */
> + reg_set &= ~(1 << ARM_IP);
> + reg_set |= (1 << ARM_SP);
> + emit(ARM_LDM(ARM_SP, reg_set), ctx);
> +#else
> + if (ctx->seen)
> + emit(ARM_POP(reg_set | (1 << ARM_PC)), ctx);
> + else
> + emit(ARM_BX(ARM_LR), ctx);
> +#endif
> +}
> +
> +static int16_t imm8m(u32 x)
> +{
> + u32 rot;
> +
> + for (rot = 0; rot < 16; rot++)
> + if ((x & ~ror32(0xff, 2 * rot)) == 0)
> + return rol32(x, 2 * rot) | (rot << 8);
> +
> + return -1;
> +}
> +
> +#if __LINUX_ARM_ARCH__ < 7
> +static u16 imm_offset(u32 k, struct jit_ctx *ctx)
> +{
> + unsigned i = 0, offset;
> + u16 imm;
> +
> + /* on the "fake" run we just count them (duplicates included) */
> + if (ctx->target == NULL) {
> + ctx->imm_count++;
> + return 0;
> + }
> +
> + while ((i < ctx->imm_count) && ctx->imms[i]) {
> + if (ctx->imms[i] == k)
> + break;
> + i++;
> + }
> +
> + if (ctx->imms[i] == 0)
> + ctx->imms[i] = k;
> +
> + /* constants go just after the epilogue */
> + offset = ctx->offsets[ctx->skf->len];
> + offset += ctx->prologue_bytes;
> + offset += ctx->epilogue_bytes;
> + offset += i * 4;
> +
> + ctx->target[offset / 4] = k;
> +
> + /* PC in ARM mode == address of the instruction + 8 */
> + imm = offset - (8 + ctx->idx * 4);
> +
> + return imm;
> +}
> +#endif /* __LINUX_ARM_ARCH__ */
> +
> +
> +/*
> + * Move an immediate that's not an imm8m to a core register.
> + */
> +static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx)
> +{
> +#if __LINUX_ARM_ARCH__ >= 7
> + emit(ARM_MOVW(rd, val & 0xffff), ctx);
> + if (val > 0xffff)
> + emit(ARM_MOVT(rd, val >> 16), ctx);
> +#else
> + emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx);
> +#endif
> +}
> +
> +static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx)
> +{
> + int imm12 = imm8m(val);
> +
> + if (imm12 >= 0)
> + emit(ARM_MOV_I(rd, imm12), ctx);
> + else
> + emit_mov_i_no8m(rd, val, ctx);
> +}
> +
> +#if __LINUX_ARM_ARCH__ < 7
> +
> +static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
> +{
> + _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx);
> + _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
> + _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx);
> + _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx);
> + _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx);
byte at a time is for alignment? ARMv6 can do misaligned accesses.
> + _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx);
> + _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx);
> + _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx);
> +}
> +
> +static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
> +{
> + _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
> + _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx);
> + _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx);
> +}
> +
> +
> +#else /* ARMv7 */
> +
> +static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
> +{
> + _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx);
> +#ifdef __LITTLE_ENDIAN
> + _emit(cond, ARM_REV(r_res, r_res), ctx);
> +#endif
> +}
> +
> +static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
> +{
> + _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx);
> +#ifdef __LITTLE_ENDIAN
> + _emit(cond, ARM_REV16(r_res, r_res), ctx);
> +#endif
> +}
> +
> +
> +#endif /* __LINUX_ARM_ARCH__ < 6 */
> +
> +#if __LINUX_ARM_ARCH__ >= 6
> +
Should be < 6.
It would be easier to read and less error prone if you group functions
into fewer #if or at least make the logic the same (i.e. all < or all >=).
> +static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx)
> +{
> + emit(ARM_LSL_R(ARM_R1, r_src, 8), ctx);
> + emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSL, 8), ctx);
> + emit(ARM_LSL_I(r_dst, r_dst, 8), ctx);
> + emit(ARM_LSL_R(r_dst, r_dst, 8), ctx);
> +}
> +
> +#else /* ARMv6 or ARMv7 */
> +
> +static inline void emit_swap16(u8 r_dst __maybe_unused,
> + u8 r_src __maybe_unused,
> + struct jit_ctx *ctx __maybe_unused)
> +{
> +#ifdef __LITTLE_ENDIAN
> + emit(ARM_REV16(r_dst, r_src), ctx);
> +#endif
> +}
> +
> +#endif /* __LINUX_ARM_ARCH__ < 6 */
> +
> +
> +/* Compute the immediate value for a PC-relative branch. */
> +static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx)
> +{
> + u32 imm;
> +
> + if (ctx->target == NULL)
> + return 0;
> + /*
> + * BPF allows only forward jumps and the offset of the target is
> + * still the one computed during the first pass.
> + */
> + imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8);
> +
> + return imm >> 2;
> +}
> +
> +#define OP_IMM3(op, r1, r2, imm_val, ctx) \
> + do { \
> + imm12 = imm8m(imm_val); \
> + if (imm12 < 0) { \
> + emit_mov_i_no8m(r_scratch, imm_val, ctx); \
> + emit(op ## _R((r1), (r2), r_scratch), ctx); \
> + } else { \
> + emit(op ## _I((r1), (r2), imm12), ctx); \
> + } \
> + } while (0)
> +
> +static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx)
> +{
> + if (ctx->ret0_fp_idx >= 0) {
> + _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx);
> + /* NOP to keep the size constant between passes */
> + emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx);
> + } else {
> + _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx);
> + _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx);
> + }
> +}
> +
> +static int build_body(struct jit_ctx *ctx)
> +{
> + void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
> + const struct sk_filter *prog = ctx->skf;
> + const struct sock_filter *inst;
> + unsigned i, load_order, off, condt, condf;
> + int imm12;
> + u32 k;
> +
> + for (i = 0; i < prog->len; i++) {
> + inst = &(prog->insns[i]);
> + /* K as an immediate value operand */
> + k = inst->k;
> +
> + /* compute offsets only in the fake pass */
> + if (ctx->target == NULL)
> + ctx->offsets[i] = ctx->idx * 4;
> +
> + switch (inst->code) {
> + case BPF_S_LD_IMM:
> + emit_mov_i(r_A, k, ctx);
> + break;
> + case BPF_S_LD_W_LEN:
> + ctx->seen |= SEEN_LEN;
> + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
> + emit(ARM_LDR_I(r_A, r_skb,
> + offsetof(struct sk_buff, len)), ctx);
> + break;
> + case BPF_S_LD_MEM:
> + /* A = scratch[k] */
> + ctx->seen |= SEEN_MEM_WORD(k);
> + emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
> + break;
> + case BPF_S_LD_W_ABS:
> + load_order = 2;
> + goto load;
> + case BPF_S_LD_H_ABS:
> + load_order = 1;
> + goto load;
> + case BPF_S_LD_B_ABS:
> + load_order = 0;
> +load:
> + emit_mov_i(r_off, k, ctx);
> +load_common:
> + ctx->seen |= SEEN_DATA | SEEN_CALL;
> +
> + if (load_order > 0) {
> + emit(ARM_SUB_I(r_scratch, r_skb_hl,
> + 1 << load_order), ctx);
> + emit(ARM_CMP_R(r_scratch, r_off), ctx);
> + condt = ARM_COND_HS;
> + } else {
> + emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
> + condt = ARM_COND_HI;
> + }
> +
> + _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
> + ctx);
> +
> + if (load_order == 0)
> + _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0),
> + ctx);
> + else if (load_order == 1)
> + emit_load_be16(condt, r_A, r_scratch, ctx);
> + else if (load_order == 2)
> + emit_load_be32(condt, r_A, r_scratch, ctx);
> +
> + _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx);
> +
> + /* the slowpath */
> + emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx);
> + emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
> + /* the offset is already in R1 */
> + emit(ARM_BLX_R(ARM_R3), ctx);
BLX is v5+ only. It probably fine to make the JIT v5+ only. There's
probably not much v4 h/w that would use this.
Rob
^ permalink raw reply
* Re: WARNING: at mm/slub.c:3357, kernel BUG at mm/slub.c:3413
From: Eric W. Biederman @ 2011-12-19 3:21 UTC (permalink / raw)
To: Markus Trippelsdorf
Cc: Eric Dumazet, Alex,Shi, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Christoph Lameter, Pekka Enberg, Matt Mackall,
netdev@vger.kernel.org, tj
In-Reply-To: <20111122083630.GA1672@x4.trippels.de>
Markus Trippelsdorf <markus@trippelsdorf.de> writes:
> On 2011.11.21 at 17:34 +0100, Markus Trippelsdorf wrote:
>> On 2011.11.21 at 17:10 +0100, Markus Trippelsdorf wrote:
>> > On 2011.11.21 at 16:48 +0100, Eric Dumazet wrote:
>> > > Le lundi 21 novembre 2011 à 16:36 +0100, Markus Trippelsdorf a écrit :
>> > > > On 2011.11.21 at 15:16 +0100, Eric Dumazet wrote:
>> > > > > Le lundi 21 novembre 2011 à 14:15 +0100, Markus Trippelsdorf a écrit :
>> > > > >
>> > > > > > I've enabled CONFIG_SLUB_DEBUG_ON and this is what happend:
>> > > > > >
>> > > > >
>> > > > > Thanks
>> > > > >
>> > > > > Please continue to provide more samples.
>> > > > >
>> > > > > There is something wrong somewhere, but where exactly, its hard to say.
>> > > >
>> > > > New sample. This one points to lib/idr.c:
>> > > >
>> > > > =============================================================================
>> > > > BUG idr_layer_cache: Poison overwritten
>> > > > -----------------------------------------------------------------------------
>> > >
>> > > Thanks, could you now add "CONFIG_DEBUG_PAGEALLOC=y" in your config as
>> > > well ?
>> >
>> > Sure. This one happend with CONFIG_DEBUG_PAGEALLOC=y:
>> >
>> > =============================================================================
>> > BUG task_struct: Poison overwritten
>> > -----------------------------------------------------------------------------
>>
>> And sometimes this one that I've reported earlier already:
>>
>> (see: http://thread.gmane.org/gmane.linux.kernel/1215023 )
>>
>> ------------[ cut here ]------------
>> WARNING: at fs/sysfs/sysfs.h:195 sysfs_get_inode+0x136/0x140()
>> Hardware name: System Product Name
>> Pid: 1876, comm: slabinfo Not tainted 3.2.0-rc2-00274-g6fe4c6d #72
>> Call Trace:
>> [<ffffffff8106cac5>] warn_slowpath_common+0x75/0xb0
>> [<ffffffff8106cbc5>] warn_slowpath_null+0x15/0x20
>> [<ffffffff81163236>] sysfs_get_inode+0x136/0x140
>> [<ffffffff81164cef>] sysfs_lookup+0x6f/0x110
>> [<ffffffff811173f9>] d_alloc_and_lookup+0x39/0x80
>> [<ffffffff81118774>] do_lookup+0x294/0x3a0
>> [<ffffffff8111798a>] ? inode_permission+0x7a/0xb0
>> [<ffffffff8111a3f7>] do_last.isra.46+0x137/0x7f0
>> [<ffffffff8111ab76>] path_openat+0xc6/0x370
>> [<ffffffff81117606>] ? getname_flags+0x36/0x230
>> [<ffffffff810ec852>] ? handle_mm_fault+0x192/0x290
>> [<ffffffff8111ae5c>] do_filp_open+0x3c/0x90
>> [<ffffffff81127c8c>] ? alloc_fd+0xdc/0x120
>> [<ffffffff8110ce77>] do_sys_open+0xe7/0x1c0
>> [<ffffffff8110cf6b>] sys_open+0x1b/0x20
>> [<ffffffff814ccb7b>] system_call_fastpath+0x16/0x1b
>> ---[ end trace b1377eb8b131d37d ]---
>
> Hm, the "sysfs: use rb-tree" thing hit again during boot. Could this be
> the root cause of this all?
>
> I wrote down the following:
>
> RIP : rb_next
>
> Trace:
> sysfs_dir_pos
> sysfs_readdir
> ? sys_ioctl
> vfs_readdir
> sys_getdents
Thanks for reporting this.
Has this by any chance been resolved or stopped happening?
This looks for all of the world like something is stomping your sysfs
dirents. I haven't seen anyone else complaining so this seems like the
problem is unique to your configuration. Which suggests that it is not
sysfs itself that is wrong.
I have been through the code a time or two and I haven't seen anything
obviously wrong. Everything that sysfs does is protected by the
sysfs_mutex so the locking is very very simple.
My best guess of why now is that the rbtree code make a sysfs dirent
48 bytes larger. And so it is much more exposed to these kinds of
problems.
Eric
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH linux-firmware] linux-firmware: bnx2: Update mips firmware to fix iSCSI problems
From: Michael Chan @ 2011-12-19 4:13 UTC (permalink / raw)
To: dwmw2; +Cc: netdev
New firmware fixes iSCSI problems with some LeftHand targets that don't
set TTT=0xffffffff for Data-In according to spec. Firmware generates
exception warnings for this condition and becomes very slow. This is
fixed by suppressing these warnings when using default error mask.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
WHENCE | 2 ++
bnx2/bnx2-mips-06-6.2.3.fw | Bin 0 -> 92824 bytes
bnx2/bnx2-mips-09-6.2.1b.fw | Bin 0 -> 103904 bytes
3 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 bnx2/bnx2-mips-06-6.2.3.fw
create mode 100644 bnx2/bnx2-mips-09-6.2.1b.fw
diff --git a/WHENCE b/WHENCE
index 01fa5ca..9832582 100644
--- a/WHENCE
+++ b/WHENCE
@@ -1050,12 +1050,14 @@ File: bnx2/bnx2-mips-06-5.0.0.j3.fw
File: bnx2/bnx2-mips-06-5.0.0.j6.fw
File: bnx2/bnx2-mips-06-6.0.15.fw
File: bnx2/bnx2-mips-06-6.2.1.fw
+File: bnx2/bnx2-mips-06-6.2.3.fw
File: bnx2/bnx2-mips-09-4.6.17.fw
File: bnx2/bnx2-mips-09-5.0.0.j3.fw
File: bnx2/bnx2-mips-09-5.0.0.j9.fw
File: bnx2/bnx2-mips-09-6.0.17.fw
File: bnx2/bnx2-mips-09-6.2.1.fw
File: bnx2/bnx2-mips-09-6.2.1a.fw
+File: bnx2/bnx2-mips-09-6.2.1b.fw
File: bnx2/bnx2-rv2p-06-4.6.16.fw
File: bnx2/bnx2-rv2p-06-5.0.0.j3.fw
File: bnx2/bnx2-rv2p-06-6.0.15.fw
diff --git a/bnx2/bnx2-mips-06-6.2.3.fw b/bnx2/bnx2-mips-06-6.2.3.fw
new file mode 100644
index 0000000000000000000000000000000000000000..7e9e54b61a6483ca1de12306a16a9cd5b8b3c945
GIT binary patch
literal 92824
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%0DrX00`ZAp1
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
literal 0
HcmV?d00001
diff --git a/bnx2/bnx2-mips-09-6.2.1b.fw b/bnx2/bnx2-mips-09-6.2.1b.fw
new file mode 100644
index 0000000000000000000000000000000000000000..8bd1e7992f55ae876d88a8af73eb4c0b4ed5972f
GIT binary patch
literal 103904
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⪻!1;^KN-(j(MuebL(3DMV*-UFN?rX)+8
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
literal 0
HcmV?d00001
--
1.7.1
^ permalink raw reply related
* [PATCH net-next] bnx2: Update driver to use new mips firmware.
From: Michael Chan @ 2011-12-19 4:15 UTC (permalink / raw)
To: davem; +Cc: netdev
bnx2-mips-06-6.2.3 and bnx2-mips-09-6.2.1.b
New firmware fixes iSCSI problems with some LeftHand targets that don't
set TTT=0xffffffff for Data-In according to spec. Firmware generates
exception warnings for this condition and becomes very slow. This is
fixed by suppressing these warnings when using default error mask.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 787e175..021fb81 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -57,11 +57,11 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
-#define DRV_MODULE_VERSION "2.1.11"
-#define DRV_MODULE_RELDATE "July 20, 2011"
-#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw"
+#define DRV_MODULE_VERSION "2.2.1"
+#define DRV_MODULE_RELDATE "Dec 18, 2011"
+#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw"
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw"
-#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1a.fw"
+#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw"
#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw"
#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw"
--
1.7.1
^ permalink raw reply related
* [PATCH net-next] igb: add basic runtime PM support
From: Yan, Zheng @ 2011-12-19 5:07 UTC (permalink / raw)
To: netdev@vger.kernel.org, e1000-devel
Cc: bruce.w.allan, jesse.brandeburg, rjw, john.ronciak,
davem@davemloft.net
Use the runtime power management framework to add basic runtime PM support
to the igb driver. Namely, make the driver suspend the device when the link
is off and set it up for generating a wakeup event after the link has been
detected again. Also make the driver suspend the device when the interface
is being shut down. This feature is disabled by default.
Based on e1000e's runtime PM code.
Signed-off-by: Zheng Yan <zheng.z.yan@intel.com>
---
drivers/net/ethernet/intel/igb/igb_main.c | 151 ++++++++++++++++++++++++-----
1 files changed, 126 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 89d576c..aac529b 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -53,6 +53,7 @@
#include <linux/if_ether.h>
#include <linux/aer.h>
#include <linux/prefetch.h>
+#include <linux/pm_runtime.h>
#ifdef CONFIG_IGB_DCA
#include <linux/dca.h>
#endif
@@ -172,8 +173,18 @@ static int igb_check_vf_assignment(struct igb_adapter *adapter);
#endif
#ifdef CONFIG_PM
-static int igb_suspend(struct pci_dev *, pm_message_t);
-static int igb_resume(struct pci_dev *);
+static int igb_suspend(struct device *);
+static int igb_resume(struct device *);
+#ifdef CONFIG_PM_RUNTIME
+static int igb_runtime_suspend(struct device *dev);
+static int igb_runtime_resume(struct device *dev);
+static int igb_runtime_idle(struct device *dev);
+#endif
+static const struct dev_pm_ops igb_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(igb_suspend, igb_resume)
+ SET_RUNTIME_PM_OPS(igb_runtime_suspend, igb_runtime_resume,
+ igb_runtime_idle)
+};
#endif
static void igb_shutdown(struct pci_dev *);
#ifdef CONFIG_IGB_DCA
@@ -214,9 +225,7 @@ static struct pci_driver igb_driver = {
.probe = igb_probe,
.remove = __devexit_p(igb_remove),
#ifdef CONFIG_PM
- /* Power Management Hooks */
- .suspend = igb_suspend,
- .resume = igb_resume,
+ .driver.pm = &igb_pm_ops,
#endif
.shutdown = igb_shutdown,
.err_handler = &igb_err_handler
@@ -2111,6 +2120,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
default:
break;
}
+
+ pm_runtime_put_noidle(&pdev->dev);
return 0;
err_register:
@@ -2150,6 +2161,8 @@ static void __devexit igb_remove(struct pci_dev *pdev)
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ pm_runtime_get_noresume(&pdev->dev);
+
/*
* The watchdog timer may be rescheduled, so explicitly
* disable watchdog from being rescheduled.
@@ -2472,16 +2485,23 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
* handler is registered with the OS, the watchdog timer is started,
* and the stack is notified that the interface is ready.
**/
-static int igb_open(struct net_device *netdev)
+static int __igb_open(struct net_device *netdev, bool resuming)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
int err;
int i;
- /* disallow open during test */
- if (test_bit(__IGB_TESTING, &adapter->state))
- return -EBUSY;
+ if (!resuming) {
+ /* disallow open during test */
+ if (test_bit(__IGB_TESTING, &adapter->state))
+ return -EBUSY;
+ pm_runtime_get_sync(&pdev->dev);
+ } else if (test_bit(__IGB_TESTING, &adapter->state)) {
+ while (test_bit(__IGB_TESTING, &adapter->state))
+ msleep(100);
+ }
netif_carrier_off(netdev);
@@ -2527,6 +2547,9 @@ static int igb_open(struct net_device *netdev)
netif_tx_start_all_queues(netdev);
+ if (!resuming)
+ pm_runtime_put(&pdev->dev);
+
/* start the watchdog. */
hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task);
@@ -2541,10 +2564,17 @@ err_setup_rx:
igb_free_all_tx_resources(adapter);
err_setup_tx:
igb_reset(adapter);
+ if (!resuming)
+ pm_runtime_put(&pdev->dev);
return err;
}
+static int igb_open(struct net_device *netdev)
+{
+ return __igb_open(netdev, false);
+}
+
/**
* igb_close - Disables a network interface
* @netdev: network interface device structure
@@ -2556,21 +2586,32 @@ err_setup_tx:
* needs to be disabled. A global MAC reset is issued to stop the
* hardware, and all transmit and receive resources are freed.
**/
-static int igb_close(struct net_device *netdev)
+static int __igb_close(struct net_device *netdev, bool suspending)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));
- igb_down(adapter);
+ if (!suspending)
+ pm_runtime_get_sync(&pdev->dev);
+
+ igb_down(adapter);
igb_free_irq(adapter);
igb_free_all_tx_resources(adapter);
igb_free_all_rx_resources(adapter);
+ if (!suspending)
+ pm_runtime_put_sync(&pdev->dev);
return 0;
}
+static int igb_close(struct net_device *netdev)
+{
+ return __igb_close(netdev, false);
+}
+
/**
* igb_setup_tx_resources - allocate Tx resources (Descriptors)
* @tx_ring: tx descriptor ring (for a specific queue) to setup
@@ -3630,6 +3671,9 @@ static void igb_watchdog_task(struct work_struct *work)
link = igb_has_link(adapter);
if (link) {
+ /* Cancel scheduled suspend requests. */
+ pm_runtime_resume(netdev->dev.parent);
+
if (!netif_carrier_ok(netdev)) {
u32 ctrl;
hw->mac.ops.get_speed_and_duplex(hw,
@@ -3701,6 +3745,9 @@ static void igb_watchdog_task(struct work_struct *work)
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
+
+ pm_schedule_suspend(netdev->dev.parent,
+ MSEC_PER_SEC * 5);
}
}
@@ -6583,21 +6630,24 @@ err_inval:
return -EINVAL;
}
-static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
+static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake,
+ bool runtime)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
u32 ctrl, rctl, status;
- u32 wufc = adapter->wol;
+ u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
#endif
- netif_device_detach(netdev);
-
- if (netif_running(netdev))
- igb_close(netdev);
+ if (netif_running(netdev)) {
+ netif_device_detach(netdev);
+ __igb_close(netdev, true);
+ } else {
+ wufc &= ~E1000_WUFC_LNKC;
+ }
igb_clear_interrupt_scheme(adapter);
@@ -6656,12 +6706,13 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
}
#ifdef CONFIG_PM
-static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
+static int igb_suspend(struct device *dev)
{
int retval;
bool wake;
+ struct pci_dev *pdev = to_pci_dev(dev);
- retval = __igb_shutdown(pdev, &wake);
+ retval = __igb_shutdown(pdev, &wake, 0);
if (retval)
return retval;
@@ -6675,8 +6726,9 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int igb_resume(struct pci_dev *pdev)
+static int igb_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
@@ -6697,7 +6749,18 @@ static int igb_resume(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
- if (igb_init_interrupt_scheme(adapter)) {
+ if (!rtnl_is_locked()) {
+ /*
+ * shut up ASSERT_RTNL() warning in
+ * netif_set_real_num_tx/rx_queues.
+ */
+ rtnl_lock();
+ err = igb_init_interrupt_scheme(adapter);
+ rtnl_unlock();
+ } else {
+ err = igb_init_interrupt_scheme(adapter);
+ }
+ if (err) {
dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
return -ENOMEM;
}
@@ -6710,23 +6773,61 @@ static int igb_resume(struct pci_dev *pdev)
wr32(E1000_WUS, ~0);
- if (netif_running(netdev)) {
- err = igb_open(netdev);
+ if (netdev->flags & IFF_UP) {
+ err = __igb_open(netdev, true);
if (err)
return err;
+ netif_device_attach(netdev);
}
- netif_device_attach(netdev);
+ return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int igb_runtime_idle(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+
+ if (!netif_running(netdev) || !igb_has_link(adapter))
+ pm_schedule_suspend(dev, MSEC_PER_SEC * 5);
+
+ return -EBUSY;
+}
+
+static int igb_runtime_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ int retval;
+ bool wake;
+
+ retval = __igb_shutdown(pdev, &wake, 1);
+ if (retval)
+ return retval;
+
+ if (wake) {
+ pci_prepare_to_sleep(pdev);
+ } else {
+ pci_wake_from_d3(pdev, false);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
return 0;
}
+
+static int igb_runtime_resume(struct device *dev)
+{
+ return igb_resume(dev);
+}
+#endif /* CONFIG_PM_RUNTIME */
#endif
static void igb_shutdown(struct pci_dev *pdev)
{
bool wake;
- __igb_shutdown(pdev, &wake);
+ __igb_shutdown(pdev, &wake, 0);
if (system_state == SYSTEM_POWER_OFF) {
pci_wake_from_d3(pdev, wake);
--
1.7.7.4
------------------------------------------------------------------------------
Learn Windows Azure Live! Tuesday, Dec 13, 2011
Microsoft is holding a special Learn Windows Azure training event for
developers. It will provide a great way to learn Windows Azure and what it
provides. You can attend the event by watching it streamed LIVE online.
Learn more at http://p.sf.net/sfu/ms-windowsazure
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply related
* Re: [PATCH 14/15] module_param: make bool parameters really bool (net & drivers/net)
From: Rusty Russell @ 2011-12-19 5:38 UTC (permalink / raw)
To: Joe Perches
Cc: lkml - Kernel Mailing List, Pawel Moll, David S. Miller, netdev
In-Reply-To: <1323995620.18603.4.camel@joe2Laptop>
On Thu, 15 Dec 2011 16:33:40 -0800, Joe Perches <joe@perches.com> wrote:
> On Fri, 2011-12-16 at 09:44 +1030, Rusty Russell wrote:
> > I could, but as I was touching 457 files, so I was aiming for minimal
> > changes.
>
> > Dave, did you want a true/false cleanup too?
>
> Hi Rusty.
>
> Did you perform these transforms via spatch?
> If not, here's a trivial spatch script for those files.
>
> $ cat bool.cocci
> @@
> bool b
> @@
> -b = 0
> +b = false
> @@
> bool b
> @@
> -b = 1
> +b = true
Nice!
You missed a semicolon on each 'bool b;' line, then it worked.
Dave, here's the fixes from drivers/net and net/ *before* my patches
come into play:
From: Rusty Russell <rusty@rustcorp.com.au>
Subject: net: fix assignment of 0/1 to bool variables.
DaveM said:
Please, this kind of stuff rots forever and not using bool properly
drives me crazy.
Joe Perches <joe@perches.com> gave me the spatch script:
@@
bool b;
@@
-b = 0
+b = false
@@
bool b;
@@
-b = 1
+b = true
I merely installed coccinelle, read the documentation and took credit.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
drivers/net/ethernet/broadcom/tg3.c | 8 -
drivers/net/ethernet/brocade/bna/bnad.c | 6 -
drivers/net/ethernet/dec/tulip/de4x5.c | 4
drivers/net/ethernet/intel/e1000/e1000_main.c | 10 -
drivers/net/ethernet/intel/e1000e/netdev.c | 24 ++--
drivers/net/ethernet/intel/ixgb/ixgb_main.c | 2
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 2
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 12 +-
drivers/net/ethernet/sfc/falcon.c | 2
drivers/net/ethernet/sfc/mtd.c | 6 -
drivers/net/ethernet/sfc/siena.c | 2
drivers/net/ethernet/tile/tilepro.c | 4
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 6 -
drivers/net/wimax/i2400m/tx.c | 8 -
drivers/net/wireless/ath/ath5k/reset.c | 4
drivers/net/wireless/ath/ath6kl/init.c | 2
drivers/net/wireless/ath/ath9k/eeprom_def.c | 2
drivers/net/wireless/ath/ath9k/xmit.c | 4
drivers/net/wireless/b43/dma.c | 14 +-
drivers/net/wireless/b43/leds.c | 16 +-
drivers/net/wireless/b43/lo.c | 8 -
drivers/net/wireless/b43/main.c | 100 +++++++++---------
drivers/net/wireless/b43/phy_common.c | 8 -
drivers/net/wireless/b43/phy_g.c | 34 +++---
drivers/net/wireless/b43/phy_lp.c | 8 -
drivers/net/wireless/b43/phy_n.c | 4
drivers/net/wireless/b43/pio.c | 6 -
drivers/net/wireless/b43/xmit.c | 4
drivers/net/wireless/b43legacy/dma.c | 16 +-
drivers/net/wireless/b43legacy/leds.c | 4
drivers/net/wireless/b43legacy/main.c | 64 +++++------
drivers/net/wireless/b43legacy/radio.c | 20 +--
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 4
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | 2
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c | 32 ++---
drivers/net/wireless/iwlwifi/iwl-agn.c | 2
drivers/net/wireless/iwmc3200wifi/main.c | 2
drivers/net/wireless/iwmc3200wifi/rx.c | 12 +-
drivers/net/wireless/libertas/if_cs.c | 4
drivers/net/wireless/libertas_tf/main.c | 4
drivers/net/wireless/mac80211_hwsim.c | 4
drivers/net/wireless/mwifiex/cfg80211.c | 6 -
drivers/net/wireless/mwl8k.c | 8 -
drivers/net/wireless/rtlwifi/base.c | 2
drivers/net/wireless/rtlwifi/pci.c | 6 -
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 4
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 4
drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 4
drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 4
drivers/net/wireless/wl12xx/sdio_test.c | 12 +-
net/dccp/feat.c | 16 +-
net/dccp/options.c | 2
net/ipv4/tcp_timer.c | 4
net/mac80211/rc80211_pid_algo.c | 4
net/mac80211/scan.c | 2
net/netfilter/ipvs/ip_vs_pe_sip.c | 4
net/rfkill/rfkill-regulator.c | 6 -
net/rxrpc/ar-ack.c | 14 +-
net/rxrpc/ar-output.c | 4
62 files changed, 297 insertions(+), 297 deletions(-)
diff -u -p a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
--- a/drivers/net/ethernet/brocade/bna/bnad.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/ethernet/brocade/bna/bnad.c 2011-12-19 13:20:51.852430982 +1030
@@ -723,7 +723,7 @@ void
bnad_cb_ethport_link_status(struct bnad *bnad,
enum bna_link_status link_status)
{
- bool link_up = 0;
+ bool link_up = false;
link_up = (link_status == BNA_LINK_UP) || (link_status == BNA_CEE_UP);
@@ -3186,7 +3186,7 @@ bnad_pci_init(struct bnad *bnad,
goto disable_device;
if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
!dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
- *using_dac = 1;
+ *using_dac = true;
} else {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
@@ -3195,7 +3195,7 @@ bnad_pci_init(struct bnad *bnad,
if (err)
goto release_regions;
}
- *using_dac = 0;
+ *using_dac = false;
}
pci_set_master(pdev);
return 0;
diff -u -p a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
--- a/drivers/net/ethernet/broadcom/tg3.c 2011-11-08 09:11:59.000000000 +1030
+++ b/drivers/net/ethernet/broadcom/tg3.c 2011-12-19 13:21:27.712431901 +1030
@@ -6443,13 +6443,13 @@ static bool tg3_tx_frag_set(struct tg3_n
bool hwbug = false;
if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8)
- hwbug = 1;
+ hwbug = true;
if (tg3_4g_overflow_test(map, len))
- hwbug = 1;
+ hwbug = true;
if (tg3_40bit_overflow_test(tp, map, len))
- hwbug = 1;
+ hwbug = true;
if (tg3_flag(tp, 4K_FIFO_LIMIT)) {
u32 prvidx = *entry;
@@ -6482,7 +6482,7 @@ static bool tg3_tx_frag_set(struct tg3_n
*budget -= 1;
*entry = NEXT_TX(*entry);
} else {
- hwbug = 1;
+ hwbug = true;
tnapi->tx_buffers[prvidx].fragmented = false;
}
}
diff -u -p a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c 2011-12-19 13:21:34.488432075 +1030
@@ -662,7 +662,7 @@ static void xemaclite_rx_handler(struct
*/
static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
{
- bool tx_complete = 0;
+ bool tx_complete = false;
struct net_device *dev = dev_id;
struct net_local *lp = netdev_priv(dev);
void __iomem *base_addr = lp->base_addr;
@@ -683,7 +683,7 @@ static irqreturn_t xemaclite_interrupt(i
tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK;
out_be32(base_addr + XEL_TSR_OFFSET, tx_status);
- tx_complete = 1;
+ tx_complete = true;
}
/* Check if the Transmission for the second buffer is completed */
@@ -695,7 +695,7 @@ static irqreturn_t xemaclite_interrupt(i
out_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET,
tx_status);
- tx_complete = 1;
+ tx_complete = true;
}
/* If there was a Tx interrupt, call the Tx Handler */
diff -u -p a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c
--- a/drivers/net/ethernet/tile/tilepro.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/tile/tilepro.c 2011-12-19 13:21:38.836432185 +1030
@@ -1256,7 +1256,7 @@ static void tile_net_stop_aux(struct net
sizeof(dummy), NETIO_IPP_STOP_SHIM_OFF) < 0)
panic("Failed to stop LIPP/LEPP!\n");
- priv->partly_opened = 0;
+ priv->partly_opened = false;
}
@@ -1507,7 +1507,7 @@ static int tile_net_open(struct net_devi
priv->network_cpus_count, priv->network_cpus_credits);
#endif
- priv->partly_opened = 1;
+ priv->partly_opened = true;
} else {
/* FIXME: Is this possible? */
diff -u -p a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c
--- a/drivers/net/ethernet/dec/tulip/de4x5.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c 2011-12-19 13:21:44.996432344 +1030
@@ -5196,7 +5196,7 @@ de4x5_parse_params(struct net_device *de
struct de4x5_private *lp = netdev_priv(dev);
char *p, *q, t;
- lp->params.fdx = 0;
+ lp->params.fdx = false;
lp->params.autosense = AUTO;
if (args == NULL) return;
@@ -5206,7 +5206,7 @@ de4x5_parse_params(struct net_device *de
t = *q;
*q = '\0';
- if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1;
+ if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = true;
if (strstr(p, "autosense") || strstr(p, "AUTOSENSE")) {
if (strstr(p, "TP")) {
diff -u -p a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 2011-12-19 13:21:49.912432469 +1030
@@ -4019,7 +4019,7 @@ void ixgbe_down(struct ixgbe_adapter *ad
/* Mark all the VFs as inactive */
for (i = 0 ; i < adapter->num_vfs; i++)
- adapter->vfinfo[i].clear_to_send = 0;
+ adapter->vfinfo[i].clear_to_send = false;
/* ping all the active vfs to let them know we are going down */
ixgbe_ping_all_vfs(adapter);
diff -u -p a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c 2011-12-19 13:21:51.424432508 +1030
@@ -1214,7 +1214,7 @@ s32 ixgbe_read_i2c_byte_generic(struct i
u32 max_retry = 10;
u32 retry = 0;
u16 swfw_mask = 0;
- bool nack = 1;
+ bool nack = true;
*data = 0;
if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
@@ -1421,7 +1421,7 @@ static void ixgbe_i2c_stop(struct ixgbe_
static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
{
s32 i;
- bool bit = 0;
+ bool bit = false;
for (i = 7; i >= 0; i--) {
ixgbe_clock_in_i2c_bit(hw, &bit);
@@ -1443,7 +1443,7 @@ static s32 ixgbe_clock_out_i2c_byte(stru
s32 status = 0;
s32 i;
u32 i2cctl;
- bool bit = 0;
+ bool bit = false;
for (i = 7; i >= 0; i--) {
bit = (data >> i) & 0x1;
@@ -1473,7 +1473,7 @@ static s32 ixgbe_get_i2c_ack(struct ixgb
u32 i = 0;
u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
u32 timeout = 10;
- bool ack = 1;
+ bool ack = true;
ixgbe_raise_i2c_clk(hw, &i2cctl);
@@ -1646,9 +1646,9 @@ static bool ixgbe_get_i2c_data(u32 *i2cc
bool data;
if (*i2cctl & IXGBE_I2C_DATA_IN)
- data = 1;
+ data = true;
else
- data = 0;
+ data = false;
return data;
}
diff -u -p a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c 2011-12-19 13:21:51.876432519 +1030
@@ -2599,7 +2599,7 @@ s32 ixgbe_enable_rx_dma_generic(struct i
s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
{
ixgbe_link_speed speed = 0;
- bool link_up = 0;
+ bool link_up = false;
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
diff -u -p a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
--- a/drivers/net/ethernet/intel/e1000e/netdev.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c 2011-12-19 13:21:53.888432571 +1030
@@ -875,7 +875,7 @@ static bool e1000_clean_rx_irq(struct e1
u32 length, staterr;
unsigned int i;
int cleaned_count = 0;
- bool cleaned = 0;
+ bool cleaned = false;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
i = rx_ring->next_to_clean;
@@ -904,7 +904,7 @@ static bool e1000_clean_rx_irq(struct e1
next_buffer = &rx_ring->buffer_info[i];
- cleaned = 1;
+ cleaned = true;
cleaned_count++;
dma_unmap_single(&pdev->dev,
buffer_info->dma,
@@ -1150,7 +1150,7 @@ static bool e1000_clean_tx_irq(struct e1
* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i
*/
- adapter->detect_tx_hung = 0;
+ adapter->detect_tx_hung = false;
if (tx_ring->buffer_info[i].time_stamp &&
time_after(jiffies, tx_ring->buffer_info[i].time_stamp
+ (adapter->tx_timeout_factor * HZ)) &&
@@ -1185,7 +1185,7 @@ static bool e1000_clean_rx_irq_ps(struct
unsigned int i, j;
u32 length, staterr;
int cleaned_count = 0;
- bool cleaned = 0;
+ bool cleaned = false;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
i = rx_ring->next_to_clean;
@@ -1211,7 +1211,7 @@ static bool e1000_clean_rx_irq_ps(struct
next_buffer = &rx_ring->buffer_info[i];
- cleaned = 1;
+ cleaned = true;
cleaned_count++;
dma_unmap_single(&pdev->dev, buffer_info->dma,
adapter->rx_ps_bsize0, DMA_FROM_DEVICE);
@@ -4183,7 +4183,7 @@ static void e1000_print_link_info(struct
static bool e1000e_has_link(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- bool link_active = 0;
+ bool link_active = false;
s32 ret_val = 0;
/*
@@ -4198,7 +4198,7 @@ static bool e1000e_has_link(struct e1000
ret_val = hw->mac.ops.check_for_link(hw);
link_active = !hw->mac.get_link_status;
} else {
- link_active = 1;
+ link_active = true;
}
break;
case e1000_media_type_fiber:
@@ -4297,7 +4297,7 @@ static void e1000_watchdog_task(struct w
if (link) {
if (!netif_carrier_ok(netdev)) {
- bool txb2b = 1;
+ bool txb2b = true;
/* Cancel scheduled suspend requests. */
pm_runtime_resume(netdev->dev.parent);
@@ -4333,11 +4333,11 @@ static void e1000_watchdog_task(struct w
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
case SPEED_10:
- txb2b = 0;
+ txb2b = false;
adapter->tx_timeout_factor = 16;
break;
case SPEED_100:
- txb2b = 0;
+ txb2b = false;
adapter->tx_timeout_factor = 10;
break;
}
@@ -4473,7 +4473,7 @@ link_up:
e1000e_flush_descriptors(adapter);
/* Force detection of hung controller every watchdog period */
- adapter->detect_tx_hung = 1;
+ adapter->detect_tx_hung = true;
/*
* With 82571 controllers, LAA may be overwritten due to controller
@@ -6135,7 +6135,7 @@ static int __devinit e1000_probe(struct
/* Initialize link parameters. User can change them with ethtool */
adapter->hw.mac.autoneg = 1;
- adapter->fc_autoneg = 1;
+ adapter->fc_autoneg = true;
adapter->hw.fc.requested_mode = e1000_fc_default;
adapter->hw.fc.current_mode = e1000_fc_default;
adapter->hw.phy.autoneg_advertised = 0x2f;
diff -u -p a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c 2011-12-19 13:21:55.904432623 +1030
@@ -228,7 +228,7 @@ ixgb_up(struct ixgb_adapter *adapter)
if (IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_PCIX_MODE) {
err = pci_enable_msi(adapter->pdev);
if (!err) {
- adapter->have_msi = 1;
+ adapter->have_msi = true;
irq_flags = 0;
}
/* proceed to try to request regular interrupt */
diff -u -p a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c 2011-12-19 13:21:57.640432667 +1030
@@ -1182,7 +1182,7 @@ static int __devinit e1000_probe(struct
if (global_quad_port_a != 0)
adapter->eeprom_wol = 0;
else
- adapter->quad_port_a = 1;
+ adapter->quad_port_a = true;
/* Reset for multiple quad port adapters */
if (++global_quad_port_a == 4)
global_quad_port_a = 0;
@@ -1676,7 +1676,7 @@ static void e1000_configure_tx(struct e1
* need this to apply a workaround later in the send path. */
if (hw->mac_type == e1000_82544 &&
hw->bus_type == e1000_bus_type_pcix)
- adapter->pcix_82544 = 1;
+ adapter->pcix_82544 = true;
ew32(TCTL, tctl);
@@ -1999,7 +1999,7 @@ static void e1000_clean_tx_ring(struct e
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- tx_ring->last_tx_tso = 0;
+ tx_ring->last_tx_tso = false;
writel(0, hw->hw_addr + tx_ring->tdh);
writel(0, hw->hw_addr + tx_ring->tdt);
@@ -2848,7 +2848,7 @@ static int e1000_tx_map(struct e1000_ada
* DMA'd to the controller */
if (!skb->data_len && tx_ring->last_tx_tso &&
!skb_is_gso(skb)) {
- tx_ring->last_tx_tso = 0;
+ tx_ring->last_tx_tso = false;
size -= 4;
}
@@ -3216,7 +3216,7 @@ static netdev_tx_t e1000_xmit_frame(stru
if (likely(tso)) {
if (likely(hw->mac_type != e1000_82544))
- tx_ring->last_tx_tso = 1;
+ tx_ring->last_tx_tso = true;
tx_flags |= E1000_TX_FLAGS_TSO;
} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
tx_flags |= E1000_TX_FLAGS_CSUM;
diff -u -p a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
--- a/drivers/net/ethernet/sfc/siena.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/sfc/siena.c 2011-12-19 13:22:00.428432738 +1030
@@ -232,7 +232,7 @@ static int siena_probe_nvconfig(struct e
static int siena_probe_nic(struct efx_nic *efx)
{
struct siena_nic_data *nic_data;
- bool already_attached = 0;
+ bool already_attached = false;
efx_oword_t reg;
int rc;
diff -u -p a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
--- a/drivers/net/ethernet/sfc/falcon.c 2011-10-31 13:28:01.000000000 +1030
+++ b/drivers/net/ethernet/sfc/falcon.c 2011-12-19 13:22:01.600432768 +1030
@@ -610,7 +610,7 @@ static void falcon_stats_complete(struct
if (!nic_data->stats_pending)
return;
- nic_data->stats_pending = 0;
+ nic_data->stats_pending = false;
if (*nic_data->stats_dma_done == FALCON_STATS_DONE) {
rmb(); /* read the done flag before the stats */
efx->mac_op->update_stats(efx);
diff -u -p a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c
--- a/drivers/net/ethernet/sfc/mtd.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/ethernet/sfc/mtd.c 2011-12-19 13:22:02.460432790 +1030
@@ -496,7 +496,7 @@ static int siena_mtd_erase(struct mtd_in
rc = efx_mcdi_nvram_update_start(efx, part->mcdi.nvram_type);
if (rc)
goto out;
- part->mcdi.updating = 1;
+ part->mcdi.updating = true;
}
/* The MCDI interface can in fact do multiple erase blocks at once;
@@ -528,7 +528,7 @@ static int siena_mtd_write(struct mtd_in
rc = efx_mcdi_nvram_update_start(efx, part->mcdi.nvram_type);
if (rc)
goto out;
- part->mcdi.updating = 1;
+ part->mcdi.updating = true;
}
while (offset < end) {
@@ -553,7 +553,7 @@ static int siena_mtd_sync(struct mtd_inf
int rc = 0;
if (part->mcdi.updating) {
- part->mcdi.updating = 0;
+ part->mcdi.updating = false;
rc = efx_mcdi_nvram_update_finish(efx, part->mcdi.nvram_type);
}
diff -u -p a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
--- a/drivers/net/wimax/i2400m/tx.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wimax/i2400m/tx.c 2011-12-19 13:22:07.120432910 +1030
@@ -562,7 +562,7 @@ void i2400m_tx_new(struct i2400m *i2400m
{
struct device *dev = i2400m_dev(i2400m);
struct i2400m_msg_hdr *tx_msg;
- bool try_head = 0;
+ bool try_head = false;
BUG_ON(i2400m->tx_msg != NULL);
/*
* In certain situations, TX queue might have enough space to
@@ -580,7 +580,7 @@ try_head:
else if (tx_msg == TAIL_FULL) {
i2400m_tx_skip_tail(i2400m);
d_printf(2, dev, "new TX message: tail full, trying head\n");
- try_head = 1;
+ try_head = true;
goto try_head;
}
memset(tx_msg, 0, I2400M_TX_PLD_SIZE);
@@ -720,7 +720,7 @@ int i2400m_tx(struct i2400m *i2400m, con
unsigned long flags;
size_t padded_len;
void *ptr;
- bool try_head = 0;
+ bool try_head = false;
unsigned is_singleton = pl_type == I2400M_PT_RESET_WARM
|| pl_type == I2400M_PT_RESET_COLD;
@@ -771,7 +771,7 @@ try_new:
d_printf(2, dev, "pl append: tail full\n");
i2400m_tx_close(i2400m);
i2400m_tx_skip_tail(i2400m);
- try_head = 1;
+ try_head = true;
goto try_new;
} else if (ptr == NULL) { /* All full */
result = -ENOSPC;
diff -u -p a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
--- a/drivers/net/wireless/libertas_tf/main.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/libertas_tf/main.c 2011-12-19 13:22:13.096433063 +1030
@@ -719,11 +719,11 @@ void lbtf_bcn_sent(struct lbtf_private *
return;
if (skb_queue_empty(&priv->bc_ps_buf)) {
- bool tx_buff_bc = 0;
+ bool tx_buff_bc = false;
while ((skb = ieee80211_get_buffered_bc(priv->hw, priv->vif))) {
skb_queue_tail(&priv->bc_ps_buf, skb);
- tx_buff_bc = 1;
+ tx_buff_bc = true;
}
if (tx_buff_bc) {
ieee80211_stop_queues(priv->hw);
diff -u -p a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
--- a/drivers/net/wireless/mwifiex/cfg80211.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/mwifiex/cfg80211.c 2011-12-19 13:22:19.348433223 +1030
@@ -753,7 +753,7 @@ mwifiex_cfg80211_disconnect(struct wiphy
if (priv->disconnect)
return -EBUSY;
- priv->disconnect = 1;
+ priv->disconnect = true;
if (mwifiex_deauthenticate(priv, NULL))
return -EFAULT;
@@ -1054,7 +1054,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy
if (priv->disconnect)
return -EBUSY;
- priv->disconnect = 1;
+ priv->disconnect = true;
wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
priv->cfg_bssid);
@@ -1498,6 +1498,6 @@ mwifiex_cfg80211_results(struct work_str
if (priv->disconnect) {
memset(priv->cfg_bssid, 0, ETH_ALEN);
- priv->disconnect = 0;
+ priv->disconnect = false;
}
}
diff -u -p a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
--- a/drivers/net/wireless/b43legacy/dma.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/b43legacy/dma.c 2011-12-19 13:22:20.264433247 +1030
@@ -715,7 +715,7 @@ struct b43legacy_dmaring *b43legacy_setu
ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
ring->index = controller_index;
if (for_tx) {
- ring->tx = 1;
+ ring->tx = true;
ring->current_slot = -1;
} else {
if (ring->index == 0) {
@@ -806,7 +806,7 @@ void b43legacy_dma_free(struct b43legacy
static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask)
{
u64 orig_mask = mask;
- bool fallback = 0;
+ bool fallback = false;
int err;
/* Try to set the DMA mask. If it fails, try falling back to a
@@ -820,12 +820,12 @@ static int b43legacy_dma_set_mask(struct
}
if (mask == DMA_BIT_MASK(64)) {
mask = DMA_BIT_MASK(32);
- fallback = 1;
+ fallback = true;
continue;
}
if (mask == DMA_BIT_MASK(32)) {
mask = DMA_BIT_MASK(30);
- fallback = 1;
+ fallback = true;
continue;
}
b43legacyerr(dev->wl, "The machine/kernel does not support "
@@ -858,7 +858,7 @@ int b43legacy_dma_init(struct b43legacy_
#ifdef CONFIG_B43LEGACY_PIO
b43legacywarn(dev->wl, "DMA for this device not supported. "
"Falling back to PIO\n");
- dev->__using_pio = 1;
+ dev->__using_pio = true;
return -EAGAIN;
#else
b43legacyerr(dev->wl, "DMA for this device not supported and "
@@ -1068,7 +1068,7 @@ static int dma_tx_fragment(struct b43leg
memset(meta, 0, sizeof(*meta));
meta->skb = skb;
- meta->is_last_fragment = 1;
+ meta->is_last_fragment = true;
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
/* create a bounce buffer in zone_dma on mapping failure. */
@@ -1187,7 +1187,7 @@ int b43legacy_dma_tx(struct b43legacy_wl
should_inject_overflow(ring)) {
/* This TX ring is full. */
ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring));
- ring->stopped = 1;
+ ring->stopped = true;
if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
b43legacydbg(dev->wl, "Stopped TX ring %d\n",
ring->index);
@@ -1286,7 +1286,7 @@ void b43legacy_dma_handle_txstatus(struc
if (ring->stopped) {
B43legacy_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring));
- ring->stopped = 0;
+ ring->stopped = false;
if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
b43legacydbg(dev->wl, "Woke up TX ring %d\n",
ring->index);
diff -u -p a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
--- a/drivers/net/wireless/b43legacy/radio.c 2011-07-26 13:50:42.000000000 +0930
+++ b/drivers/net/wireless/b43legacy/radio.c 2011-12-19 13:22:20.964433265 +1030
@@ -1067,7 +1067,7 @@ b43legacy_radio_interference_mitigation_
if (b43legacy_phy_read(dev, 0x0033) & 0x0800)
break;
- phy->aci_enable = 1;
+ phy->aci_enable = true;
phy_stacksave(B43legacy_PHY_RADIO_BITFIELD);
phy_stacksave(B43legacy_PHY_G_CRS);
@@ -1279,7 +1279,7 @@ b43legacy_radio_interference_mitigation_
if (!(b43legacy_phy_read(dev, 0x0033) & 0x0800))
break;
- phy->aci_enable = 0;
+ phy->aci_enable = false;
phy_stackrestore(B43legacy_PHY_RADIO_BITFIELD);
phy_stackrestore(B43legacy_PHY_G_CRS);
@@ -1346,10 +1346,10 @@ int b43legacy_radio_set_interference_mit
(phy->rev == 0) || (!phy->gmode))
return -ENODEV;
- phy->aci_wlan_automatic = 0;
+ phy->aci_wlan_automatic = false;
switch (mode) {
case B43legacy_RADIO_INTERFMODE_AUTOWLAN:
- phy->aci_wlan_automatic = 1;
+ phy->aci_wlan_automatic = true;
if (phy->aci_enable)
mode = B43legacy_RADIO_INTERFMODE_MANUALWLAN;
else
@@ -1371,8 +1371,8 @@ int b43legacy_radio_set_interference_mit
currentmode);
if (mode == B43legacy_RADIO_INTERFMODE_NONE) {
- phy->aci_enable = 0;
- phy->aci_hw_rssi = 0;
+ phy->aci_enable = false;
+ phy->aci_hw_rssi = false;
} else
b43legacy_radio_interference_mitigation_enable(dev, mode);
phy->interfmode = mode;
@@ -2102,7 +2102,7 @@ void b43legacy_radio_turn_on(struct b43l
phy->radio_off_context.rfover);
b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL,
phy->radio_off_context.rfoverval);
- phy->radio_off_context.valid = 0;
+ phy->radio_off_context.valid = false;
}
channel = phy->channel;
err = b43legacy_radio_selectchannel(dev,
@@ -2113,7 +2113,7 @@ void b43legacy_radio_turn_on(struct b43l
default:
B43legacy_BUG_ON(1);
}
- phy->radio_on = 1;
+ phy->radio_on = true;
}
void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force)
@@ -2131,14 +2131,14 @@ void b43legacy_radio_turn_off(struct b43
if (!force) {
phy->radio_off_context.rfover = rfover;
phy->radio_off_context.rfoverval = rfoverval;
- phy->radio_off_context.valid = 1;
+ phy->radio_off_context.valid = true;
}
b43legacy_phy_write(dev, B43legacy_PHY_RFOVER, rfover | 0x008C);
b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL,
rfoverval & 0xFF73);
} else
b43legacy_phy_write(dev, 0x0015, 0xAA00);
- phy->radio_on = 0;
+ phy->radio_on = false;
b43legacydbg(dev->wl, "Radio initialized\n");
}
diff -u -p a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c
--- a/drivers/net/wireless/b43legacy/leds.c 2011-07-26 13:50:42.000000000 +0930
+++ b/drivers/net/wireless/b43legacy/leds.c 2011-12-19 13:22:21.536433279 +1030
@@ -203,11 +203,11 @@ void b43legacy_leds_init(struct b43legac
if (sprom[i] == 0xFF) {
/* There is no LED information in the SPROM
* for this LED. Hardcode it here. */
- activelow = 0;
+ activelow = false;
switch (i) {
case 0:
behaviour = B43legacy_LED_ACTIVITY;
- activelow = 1;
+ activelow = true;
if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
behaviour = B43legacy_LED_RADIO_ALL;
break;
diff -u -p a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
--- a/drivers/net/wireless/b43legacy/main.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/b43legacy/main.c 2011-12-19 13:22:22.200433296 +1030
@@ -722,9 +722,9 @@ void b43legacy_wireless_core_reset(struc
macctl &= ~B43legacy_MACCTL_GMODE;
if (flags & B43legacy_TMSLOW_GMODE) {
macctl |= B43legacy_MACCTL_GMODE;
- dev->phy.gmode = 1;
+ dev->phy.gmode = true;
} else
- dev->phy.gmode = 0;
+ dev->phy.gmode = false;
macctl |= B43legacy_MACCTL_IHR_ENABLED;
b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
}
@@ -811,7 +811,7 @@ static void b43legacy_calculate_link_qua
if (dev->noisecalc.calculation_running)
return;
dev->noisecalc.channel_at_start = dev->phy.channel;
- dev->noisecalc.calculation_running = 1;
+ dev->noisecalc.calculation_running = true;
dev->noisecalc.nr_samples = 0;
b43legacy_generate_noise_sample(dev);
@@ -873,7 +873,7 @@ static void handle_irq_noise(struct b43l
dev->stats.link_noise = average;
drop_calculation:
- dev->noisecalc.calculation_running = 0;
+ dev->noisecalc.calculation_running = false;
return;
}
generate_new:
@@ -889,7 +889,7 @@ static void handle_irq_tbtt_indication(s
b43legacy_power_saving_ctl_bits(dev, -1, -1);
}
if (b43legacy_is_mode(dev->wl, NL80211_IFTYPE_ADHOC))
- dev->dfq_valid = 1;
+ dev->dfq_valid = true;
}
static void handle_irq_atim_end(struct b43legacy_wldev *dev)
@@ -898,7 +898,7 @@ static void handle_irq_atim_end(struct b
b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
| B43legacy_MACCMD_DFQ_VALID);
- dev->dfq_valid = 0;
+ dev->dfq_valid = false;
}
}
@@ -971,7 +971,7 @@ static void b43legacy_write_beacon_templ
unsigned int i, len, variable_len;
const struct ieee80211_mgmt *bcn;
const u8 *ie;
- bool tim_found = 0;
+ bool tim_found = false;
unsigned int rate;
u16 ctl;
int antenna;
@@ -1019,7 +1019,7 @@ static void b43legacy_write_beacon_templ
/* A valid TIM is at least 4 bytes long. */
if (ie_len < 4)
break;
- tim_found = 1;
+ tim_found = true;
tim_position = sizeof(struct b43legacy_plcp_hdr6);
tim_position += offsetof(struct ieee80211_mgmt,
@@ -1172,7 +1172,7 @@ static void b43legacy_upload_beacon0(str
* but we don't use that feature anyway. */
b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
&__b43legacy_ratetable[3]);
- wl->beacon0_uploaded = 1;
+ wl->beacon0_uploaded = true;
}
static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev)
@@ -1182,7 +1182,7 @@ static void b43legacy_upload_beacon1(str
if (wl->beacon1_uploaded)
return;
b43legacy_write_beacon_template(dev, 0x468, 0x1A);
- wl->beacon1_uploaded = 1;
+ wl->beacon1_uploaded = true;
}
static void handle_irq_beacon(struct b43legacy_wldev *dev)
@@ -1212,7 +1212,7 @@ static void handle_irq_beacon(struct b43
if (unlikely(wl->beacon_templates_virgin)) {
/* We never uploaded a beacon before.
* Upload both templates now, but only mark one valid. */
- wl->beacon_templates_virgin = 0;
+ wl->beacon_templates_virgin = false;
b43legacy_upload_beacon0(dev);
b43legacy_upload_beacon1(dev);
cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
@@ -1275,8 +1275,8 @@ static void b43legacy_update_templates(s
if (wl->current_beacon)
dev_kfree_skb_any(wl->current_beacon);
wl->current_beacon = beacon;
- wl->beacon0_uploaded = 0;
- wl->beacon1_uploaded = 0;
+ wl->beacon0_uploaded = false;
+ wl->beacon1_uploaded = false;
ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
}
@@ -2510,7 +2510,7 @@ static int find_wldev_for_phymode(struct
if (d->phy.possible_phymodes & phymode) {
/* Ok, this device supports the PHY-mode.
* Set the gmode bit. */
- *gmode = 1;
+ *gmode = true;
*dev = d;
return 0;
@@ -2546,7 +2546,7 @@ static int b43legacy_switch_phymode(stru
struct b43legacy_wldev *uninitialized_var(up_dev);
struct b43legacy_wldev *down_dev;
int err;
- bool gmode = 0;
+ bool gmode = false;
int prev_status;
err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode);
@@ -3044,12 +3044,12 @@ static void setup_struct_phy_for_init(st
/* Assume the radio is enabled. If it's not enabled, the state will
* immediately get fixed on the first periodic work run. */
- dev->radio_hw_enable = 1;
+ dev->radio_hw_enable = true;
phy->savedpctlreg = 0xFFFF;
- phy->aci_enable = 0;
- phy->aci_wlan_automatic = 0;
- phy->aci_hw_rssi = 0;
+ phy->aci_enable = false;
+ phy->aci_wlan_automatic = false;
+ phy->aci_hw_rssi = false;
lo = phy->_lo_pairs;
if (lo)
@@ -3081,7 +3081,7 @@ static void setup_struct_phy_for_init(st
static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
{
/* Flags */
- dev->dfq_valid = 0;
+ dev->dfq_valid = false;
/* Stats */
memset(&dev->stats, 0, sizeof(dev->stats));
@@ -3187,9 +3187,9 @@ static void prepare_phy_data_for_init(st
phy->lofcal = 0xFFFF;
phy->initval = 0xFFFF;
- phy->aci_enable = 0;
- phy->aci_wlan_automatic = 0;
- phy->aci_hw_rssi = 0;
+ phy->aci_enable = false;
+ phy->aci_wlan_automatic = false;
+ phy->aci_hw_rssi = false;
phy->antenna_diversity = 0xFFFF;
memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
@@ -3355,7 +3355,7 @@ static int b43legacy_op_add_interface(st
b43legacydbg(wl, "Adding Interface type %d\n", vif->type);
dev = wl->current_dev;
- wl->operating = 1;
+ wl->operating = true;
wl->vif = vif;
wl->if_type = vif->type;
memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
@@ -3389,7 +3389,7 @@ static void b43legacy_op_remove_interfac
B43legacy_WARN_ON(wl->vif != vif);
wl->vif = NULL;
- wl->operating = 0;
+ wl->operating = false;
spin_lock_irqsave(&wl->irq_lock, flags);
b43legacy_adjust_opmode(dev);
@@ -3413,10 +3413,10 @@ static int b43legacy_op_start(struct iee
memset(wl->bssid, 0, ETH_ALEN);
memset(wl->mac_addr, 0, ETH_ALEN);
wl->filter_flags = 0;
- wl->beacon0_uploaded = 0;
- wl->beacon1_uploaded = 0;
- wl->beacon_templates_virgin = 1;
- wl->radio_enabled = 1;
+ wl->beacon0_uploaded = false;
+ wl->beacon1_uploaded = false;
+ wl->beacon_templates_virgin = true;
+ wl->radio_enabled = true;
mutex_lock(&wl->mutex);
@@ -3455,7 +3455,7 @@ static void b43legacy_op_stop(struct iee
if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)
b43legacy_wireless_core_stop(dev);
b43legacy_wireless_core_exit(dev);
- wl->radio_enabled = 0;
+ wl->radio_enabled = false;
mutex_unlock(&wl->mutex);
}
@@ -3614,7 +3614,7 @@ static int b43legacy_wireless_core_attac
have_bphy = 1;
dev->phy.gmode = (have_gphy || have_bphy);
- dev->phy.radio_on = 1;
+ dev->phy.radio_on = true;
tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;
b43legacy_wireless_core_reset(dev, tmp);
@@ -3705,7 +3705,7 @@ static int b43legacy_one_core_attach(str
(void (*)(unsigned long))b43legacy_interrupt_tasklet,
(unsigned long)wldev);
if (modparam_pio)
- wldev->__using_pio = 1;
+ wldev->__using_pio = true;
INIT_LIST_HEAD(&wldev->list);
err = b43legacy_wireless_core_attach(wldev);
diff -u -p a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
--- a/drivers/net/wireless/ath/ath5k/reset.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/ath/ath5k/reset.c 2011-12-19 13:22:24.384433352 +1030
@@ -1047,7 +1047,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
*/
if (fast && (ah->ah_radio != AR5K_RF2413) &&
(ah->ah_radio != AR5K_RF5413))
- fast = 0;
+ fast = false;
/* Disable sleep clock operation
* to avoid register access delay on certain
@@ -1073,7 +1073,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
if (ret && fast) {
ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
"DMA didn't stop, falling back to normal reset\n");
- fast = 0;
+ fast = false;
/* Non fatal, just continue with
* normal reset */
ret = 0;
diff -u -p a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
--- a/drivers/net/wireless/ath/ath9k/xmit.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/ath/ath9k/xmit.c 2011-12-19 13:22:33.224433577 +1030
@@ -1911,7 +1911,7 @@ int ath_tx_start(struct ieee80211_hw *hw
if (txq == sc->tx.txq_map[q] &&
++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
ieee80211_stop_queue(sc->hw, q);
- txq->stopped = 1;
+ txq->stopped = true;
}
spin_unlock_bh(&txq->axq_lock);
@@ -1970,7 +1970,7 @@ static void ath_tx_complete(struct ath_s
if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
ieee80211_wake_queue(sc->hw, q);
- txq->stopped = 0;
+ txq->stopped = false;
}
spin_unlock_bh(&txq->axq_lock);
}
diff -u -p a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c 2011-12-19 13:22:39.848433748 +1030
@@ -385,7 +385,7 @@ static int ath9k_hw_def_check_eeprom(str
if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
((eep->baseEepHeader.version & 0xff) > 0x0a) &&
(eep->baseEepHeader.pwdclkind == 0))
- ah->need_an_top2_fixup = 1;
+ ah->need_an_top2_fixup = true;
if ((common->bus_ops->ath_bus_type == ATH_USB) &&
(AR_SREV_9280(ah)))
diff -u -p a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
--- a/drivers/net/wireless/ath/ath6kl/init.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/ath/ath6kl/init.c 2011-12-19 13:22:40.680433769 +1030
@@ -453,7 +453,7 @@ static int ath6kl_target_config_wlan_par
ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P "
"capabilities (%d) - assuming P2P not "
"supported\n", ret);
- ar->p2p = 0;
+ ar->p2p = false;
}
}
diff -u -p a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c 2011-12-19 13:22:46.204433910 +1030
@@ -98,9 +98,9 @@ int rtl92c_init_sw_vars(struct ieee80211
rtl8192ce_bt_reg_init(hw);
- rtlpriv->dm.dm_initialgain_enable = 1;
+ rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
- rtlpriv->dm.disable_framebursting = 0;
+ rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
diff -u -p a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c 2011-07-26 13:50:42.000000000 +0930
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c 2011-12-19 13:22:48.932433981 +1030
@@ -2435,7 +2435,7 @@ bool rtl92cu_gpio_radio_on_off_checking(
"%x\n", ppsc->hwradiooff, e_rfpowerstate_toset));
}
if (actuallyset) {
- ppsc->hwradiooff = 1;
+ ppsc->hwradiooff = true;
if (e_rfpowerstate_toset == ERFON) {
if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM))
diff -u -p a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c 2011-12-19 13:22:49.604433997 +1030
@@ -57,9 +57,9 @@ static int rtl92cu_init_sw_vars(struct i
const struct firmware *firmware;
int err;
- rtlpriv->dm.dm_initialgain_enable = 1;
+ rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
- rtlpriv->dm.disable_framebursting = 0;
+ rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
diff -u -p a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
--- a/drivers/net/wireless/rtlwifi/pci.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/rtlwifi/pci.c 2011-12-19 13:22:50.800434029 +1030
@@ -78,7 +78,7 @@ static void _rtl_pci_update_default_sett
u8 init_aspm;
ppsc->reg_rfps_level = 0;
- ppsc->support_aspm = 0;
+ ppsc->support_aspm = false;
/*Update PCI ASPM setting */
ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm;
@@ -570,9 +570,9 @@ static void _rtl_pci_tx_isr(struct ieee8
if (ieee80211_is_nullfunc(fc)) {
if (ieee80211_has_pm(fc)) {
rtlpriv->mac80211.offchan_delay = true;
- rtlpriv->psc.state_inap = 1;
+ rtlpriv->psc.state_inap = true;
} else {
- rtlpriv->psc.state_inap = 0;
+ rtlpriv->psc.state_inap = false;
}
}
diff -u -p a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c 2011-12-19 13:22:55.252434143 +1030
@@ -98,9 +98,9 @@ static int rtl92s_init_sw_vars(struct ie
int err = 0;
u16 earlyrxthreshold = 7;
- rtlpriv->dm.dm_initialgain_enable = 1;
+ rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
- rtlpriv->dm.disable_framebursting = 0;
+ rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
rtlpriv->dm.useramask = true;
diff -u -p a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
--- a/drivers/net/wireless/rtlwifi/base.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/rtlwifi/base.c 2011-12-19 13:22:58.184434218 +1030
@@ -396,7 +396,7 @@ void rtl_init_rfkill(struct ieee80211_hw
u8 valid = 0;
/*set init state to on */
- rtlpriv->rfkill.rfkill_state = 1;
+ rtlpriv->rfkill.rfkill_state = true;
wiphy_rfkill_set_hw_state(hw->wiphy, 0);
radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
diff -u -p a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c 2011-12-19 13:23:02.968434340 +1030
@@ -99,9 +99,9 @@ static int rtl92d_init_sw_vars(struct ie
rtlpriv->dm.dm_initialgain_enable = true;
rtlpriv->dm.dm_flag = 0;
- rtlpriv->dm.disable_framebursting = 0;
+ rtlpriv->dm.disable_framebursting = false;
rtlpriv->dm.thermalvalue = 0;
- rtlpriv->dm.useramask = 1;
+ rtlpriv->dm.useramask = true;
/* dual mac */
if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
diff -u -p a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
--- a/drivers/net/wireless/b43/dma.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/b43/dma.c 2011-12-19 13:23:03.864434363 +1030
@@ -890,7 +890,7 @@ struct b43_dmaring *b43_setup_dmaring(st
else
ring->ops = &dma32_ops;
if (for_tx) {
- ring->tx = 1;
+ ring->tx = true;
ring->current_slot = -1;
} else {
if (ring->index == 0) {
@@ -1061,7 +1061,7 @@ void b43_dma_free(struct b43_wldev *dev)
static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
{
u64 orig_mask = mask;
- bool fallback = 0;
+ bool fallback = false;
int err;
/* Try to set the DMA mask. If it fails, try falling back to a
@@ -1075,12 +1075,12 @@ static int b43_dma_set_mask(struct b43_w
}
if (mask == DMA_BIT_MASK(64)) {
mask = DMA_BIT_MASK(32);
- fallback = 1;
+ fallback = true;
continue;
}
if (mask == DMA_BIT_MASK(32)) {
mask = DMA_BIT_MASK(30);
- fallback = 1;
+ fallback = true;
continue;
}
b43err(dev->wl, "The machine/kernel does not support "
@@ -1307,7 +1307,7 @@ static int dma_tx_fragment(struct b43_dm
memset(meta, 0, sizeof(*meta));
meta->skb = skb;
- meta->is_last_fragment = 1;
+ meta->is_last_fragment = true;
priv_info->bouncebuffer = NULL;
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
@@ -1466,7 +1466,7 @@ int b43_dma_tx(struct b43_wldev *dev, st
should_inject_overflow(ring)) {
/* This TX ring is full. */
ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
- ring->stopped = 1;
+ ring->stopped = true;
if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
}
@@ -1585,7 +1585,7 @@ void b43_dma_handle_txstatus(struct b43_
if (ring->stopped) {
B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
- ring->stopped = 0;
+ ring->stopped = false;
if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
}
diff -u -p a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
--- a/drivers/net/wireless/b43/lo.c 2011-07-26 13:50:42.000000000 +0930
+++ b/drivers/net/wireless/b43/lo.c 2011-12-19 13:23:04.300434374 +1030
@@ -826,7 +826,7 @@ void b43_gphy_dc_lt_init(struct b43_wlde
const struct b43_rfatt *rfatt;
const struct b43_bbatt *bbatt;
u64 power_vector;
- bool table_changed = 0;
+ bool table_changed = false;
BUILD_BUG_ON(B43_DC_LT_SIZE != 32);
B43_WARN_ON(lo->rfatt_list.len * lo->bbatt_list.len > 64);
@@ -876,7 +876,7 @@ void b43_gphy_dc_lt_init(struct b43_wlde
lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xFF00)
| (val & 0x00FF);
}
- table_changed = 1;
+ table_changed = true;
}
if (table_changed) {
/* The table changed in memory. Update the hardware table. */
@@ -938,7 +938,7 @@ void b43_lo_g_maintanance_work(struct b4
unsigned long now;
unsigned long expire;
struct b43_lo_calib *cal, *tmp;
- bool current_item_expired = 0;
+ bool current_item_expired = false;
bool hwpctl;
if (!lo)
@@ -968,7 +968,7 @@ void b43_lo_g_maintanance_work(struct b4
if (b43_compare_bbatt(&cal->bbatt, &gphy->bbatt) &&
b43_compare_rfatt(&cal->rfatt, &gphy->rfatt)) {
B43_WARN_ON(current_item_expired);
- current_item_expired = 1;
+ current_item_expired = true;
}
if (b43_debug(dev, B43_DBG_LO)) {
b43dbg(dev->wl, "LO: Item BB(%u), RF(%u,%u), "
diff -u -p a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
--- a/drivers/net/wireless/b43/phy_lp.c 2011-07-26 13:50:42.000000000 +0930
+++ b/drivers/net/wireless/b43/phy_lp.c 2011-12-19 13:23:05.520434405 +1030
@@ -736,9 +736,9 @@ static void lpphy_set_deaf(struct b43_wl
struct b43_phy_lp *lpphy = dev->phy.lp;
if (user)
- lpphy->crs_usr_disable = 1;
+ lpphy->crs_usr_disable = true;
else
- lpphy->crs_sys_disable = 1;
+ lpphy->crs_sys_disable = true;
b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x80);
}
@@ -747,9 +747,9 @@ static void lpphy_clear_deaf(struct b43_
struct b43_phy_lp *lpphy = dev->phy.lp;
if (user)
- lpphy->crs_usr_disable = 0;
+ lpphy->crs_usr_disable = false;
else
- lpphy->crs_sys_disable = 0;
+ lpphy->crs_sys_disable = false;
if (!lpphy->crs_usr_disable && !lpphy->crs_sys_disable) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
diff -u -p a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
--- a/drivers/net/wireless/b43/xmit.c 2011-11-21 11:21:33.000000000 +1030
+++ b/drivers/net/wireless/b43/xmit.c 2011-12-19 13:23:06.592434432 +1030
@@ -874,7 +874,7 @@ bool b43_fill_txstatus_report(struct b43
struct ieee80211_tx_info *report,
const struct b43_txstatus *status)
{
- bool frame_success = 1;
+ bool frame_success = true;
int retry_limit;
/* preserve the confiured retry limit before clearing the status
@@ -890,7 +890,7 @@ bool b43_fill_txstatus_report(struct b43
/* The frame was not ACKed... */
if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
/* ...but we expected an ACK. */
- frame_success = 0;
+ frame_success = false;
}
}
if (status->frame_count == 0) {
diff -u -p a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
--- a/drivers/net/wireless/b43/phy_common.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/b43/phy_common.c 2011-12-19 13:23:07.276434450 +1030
@@ -145,7 +145,7 @@ void b43_radio_lock(struct b43_wldev *de
#if B43_DEBUG
B43_WARN_ON(dev->phy.radio_locked);
- dev->phy.radio_locked = 1;
+ dev->phy.radio_locked = true;
#endif
macctl = b43_read32(dev, B43_MMIO_MACCTL);
@@ -163,7 +163,7 @@ void b43_radio_unlock(struct b43_wldev *
#if B43_DEBUG
B43_WARN_ON(!dev->phy.radio_locked);
- dev->phy.radio_locked = 0;
+ dev->phy.radio_locked = false;
#endif
/* Commit any write */
@@ -178,7 +178,7 @@ void b43_phy_lock(struct b43_wldev *dev)
{
#if B43_DEBUG
B43_WARN_ON(dev->phy.phy_locked);
- dev->phy.phy_locked = 1;
+ dev->phy.phy_locked = true;
#endif
B43_WARN_ON(dev->dev->core_rev < 3);
@@ -190,7 +190,7 @@ void b43_phy_unlock(struct b43_wldev *de
{
#if B43_DEBUG
B43_WARN_ON(!dev->phy.phy_locked);
- dev->phy.phy_locked = 0;
+ dev->phy.phy_locked = false;
#endif
B43_WARN_ON(dev->dev->core_rev < 3);
diff -u -p a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
--- a/drivers/net/wireless/b43/leds.c 2011-07-26 13:50:42.000000000 +0930
+++ b/drivers/net/wireless/b43/leds.c 2011-12-19 13:23:07.716434462 +1030
@@ -74,7 +74,7 @@ static void b43_led_update(struct b43_wl
if (radio_enabled)
turn_on = atomic_read(&led->state) != LED_OFF;
else
- turn_on = 0;
+ turn_on = false;
if (turn_on == led->hw_state)
return;
led->hw_state = turn_on;
@@ -225,11 +225,11 @@ static void b43_led_get_sprominfo(struct
if (sprom[led_index] == 0xFF) {
/* There is no LED information in the SPROM
* for this LED. Hardcode it here. */
- *activelow = 0;
+ *activelow = false;
switch (led_index) {
case 0:
*behaviour = B43_LED_ACTIVITY;
- *activelow = 1;
+ *activelow = true;
if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ)
*behaviour = B43_LED_RADIO_ALL;
break;
@@ -267,11 +267,11 @@ void b43_leds_init(struct b43_wldev *dev
if (led->wl) {
if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) {
b43_led_turn_on(dev, led->index, led->activelow);
- led->hw_state = 1;
+ led->hw_state = true;
atomic_set(&led->state, 1);
} else {
b43_led_turn_off(dev, led->index, led->activelow);
- led->hw_state = 0;
+ led->hw_state = false;
atomic_set(&led->state, 0);
}
}
@@ -280,19 +280,19 @@ void b43_leds_init(struct b43_wldev *dev
led = &dev->wl->leds.led_tx;
if (led->wl) {
b43_led_turn_off(dev, led->index, led->activelow);
- led->hw_state = 0;
+ led->hw_state = false;
atomic_set(&led->state, 0);
}
led = &dev->wl->leds.led_rx;
if (led->wl) {
b43_led_turn_off(dev, led->index, led->activelow);
- led->hw_state = 0;
+ led->hw_state = false;
atomic_set(&led->state, 0);
}
led = &dev->wl->leds.led_assoc;
if (led->wl) {
b43_led_turn_off(dev, led->index, led->activelow);
- led->hw_state = 0;
+ led->hw_state = false;
atomic_set(&led->state, 0);
}
diff -u -p a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
--- a/drivers/net/wireless/b43/phy_g.c 2011-07-26 13:50:42.000000000 +0930
+++ b/drivers/net/wireless/b43/phy_g.c 2011-12-19 13:23:08.324434477 +1030
@@ -897,7 +897,7 @@ b43_radio_interference_mitigation_enable
if (b43_phy_read(dev, 0x0033) & 0x0800)
break;
- gphy->aci_enable = 1;
+ gphy->aci_enable = true;
phy_stacksave(B43_PHY_RADIO_BITFIELD);
phy_stacksave(B43_PHY_G_CRS);
@@ -1038,7 +1038,7 @@ b43_radio_interference_mitigation_disabl
if (!(b43_phy_read(dev, 0x0033) & 0x0800))
break;
- gphy->aci_enable = 0;
+ gphy->aci_enable = false;
phy_stackrestore(B43_PHY_RADIO_BITFIELD);
phy_stackrestore(B43_PHY_G_CRS);
@@ -1956,10 +1956,10 @@ static void b43_phy_init_pctl(struct b43
bbatt.att = 11;
if (phy->radio_rev == 8) {
rfatt.att = 15;
- rfatt.with_padmix = 1;
+ rfatt.with_padmix = true;
} else {
rfatt.att = 9;
- rfatt.with_padmix = 0;
+ rfatt.with_padmix = false;
}
b43_set_txpower_g(dev, &bbatt, &rfatt, 0);
}
@@ -2137,7 +2137,7 @@ static void default_radio_attenuation(st
struct b43_bus_dev *bdev = dev->dev;
struct b43_phy *phy = &dev->phy;
- rf->with_padmix = 0;
+ rf->with_padmix = false;
if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
dev->dev->board_type == SSB_BOARD_BCM4309G) {
@@ -2221,7 +2221,7 @@ static void default_radio_attenuation(st
return;
case 8:
rf->att = 0xA;
- rf->with_padmix = 1;
+ rf->with_padmix = true;
return;
case 9:
default:
@@ -2389,7 +2389,7 @@ static int b43_gphy_init_tssi2dbm_table(
B43_WARN_ON((dev->dev->chip_id == 0x4301) &&
(phy->radio_ver != 0x2050)); /* Not supported anymore */
- gphy->dyn_tssi_tbl = 0;
+ gphy->dyn_tssi_tbl = false;
if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
pab0 != -1 && pab1 != -1 && pab2 != -1) {
@@ -2404,7 +2404,7 @@ static int b43_gphy_init_tssi2dbm_table(
pab1, pab2);
if (!gphy->tssi2dbm)
return -ENOMEM;
- gphy->dyn_tssi_tbl = 1;
+ gphy->dyn_tssi_tbl = true;
} else {
/* pabX values not set in SPROM. */
gphy->tgt_idle_tssi = 52;
@@ -2504,7 +2504,7 @@ static void b43_gphy_op_free(struct b43_
if (gphy->dyn_tssi_tbl)
kfree(gphy->tssi2dbm);
- gphy->dyn_tssi_tbl = 0;
+ gphy->dyn_tssi_tbl = false;
gphy->tssi2dbm = NULL;
kfree(gphy);
@@ -2531,10 +2531,10 @@ static int b43_gphy_op_prepare_hardware(
if (phy->rev == 1) {
/* Workaround: Temporarly disable gmode through the early init
* phase, as the gmode stuff is not needed for phy rev 1 */
- phy->gmode = 0;
+ phy->gmode = false;
b43_wireless_core_reset(dev, 0);
b43_phy_initg(dev);
- phy->gmode = 1;
+ phy->gmode = true;
b43_wireless_core_reset(dev, 1);
}
@@ -2613,7 +2613,7 @@ static void b43_gphy_op_software_rfkill(
gphy->radio_off_context.rfover);
b43_phy_write(dev, B43_PHY_RFOVERVAL,
gphy->radio_off_context.rfoverval);
- gphy->radio_off_context.valid = 0;
+ gphy->radio_off_context.valid = false;
}
channel = phy->channel;
b43_gphy_channel_switch(dev, 6, 1);
@@ -2626,7 +2626,7 @@ static void b43_gphy_op_software_rfkill(
rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
gphy->radio_off_context.rfover = rfover;
gphy->radio_off_context.rfoverval = rfoverval;
- gphy->radio_off_context.valid = 1;
+ gphy->radio_off_context.valid = true;
b43_phy_write(dev, B43_PHY_RFOVER, rfover | 0x008C);
b43_phy_write(dev, B43_PHY_RFOVERVAL, rfoverval & 0xFF73);
}
@@ -2711,10 +2711,10 @@ static int b43_gphy_op_interf_mitigation
if ((phy->rev == 0) || (!phy->gmode))
return -ENODEV;
- gphy->aci_wlan_automatic = 0;
+ gphy->aci_wlan_automatic = false;
switch (mode) {
case B43_INTERFMODE_AUTOWLAN:
- gphy->aci_wlan_automatic = 1;
+ gphy->aci_wlan_automatic = true;
if (gphy->aci_enable)
mode = B43_INTERFMODE_MANUALWLAN;
else
@@ -2735,8 +2735,8 @@ static int b43_gphy_op_interf_mitigation
b43_radio_interference_mitigation_disable(dev, currentmode);
if (mode == B43_INTERFMODE_NONE) {
- gphy->aci_enable = 0;
- gphy->aci_hw_rssi = 0;
+ gphy->aci_enable = false;
+ gphy->aci_hw_rssi = false;
} else
b43_radio_interference_mitigation_enable(dev, mode);
gphy->interfmode = mode;
diff -u -p a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
--- a/drivers/net/wireless/b43/phy_n.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/b43/phy_n.c 2011-12-19 13:23:10.480434532 +1030
@@ -3258,7 +3258,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
if (dev->phy.rev >= 4) {
avoid = nphy->hang_avoid;
- nphy->hang_avoid = 0;
+ nphy->hang_avoid = false;
}
b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
@@ -3368,7 +3368,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
if (phy6or5x && updated[core] == 0) {
b43_nphy_update_tx_cal_ladder(dev, core);
- updated[core] = 1;
+ updated[core] = true;
}
tmp = (params[core].ncorr[type] << 8) | 0x66;
diff -u -p a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
--- a/drivers/net/wireless/b43/pio.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/b43/pio.c 2011-12-19 13:23:15.428434659 +1030
@@ -539,7 +539,7 @@ int b43_pio_tx(struct b43_wldev *dev, st
/* Not enough memory on the queue. */
err = -EBUSY;
ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
- q->stopped = 1;
+ q->stopped = true;
goto out;
}
@@ -566,7 +566,7 @@ int b43_pio_tx(struct b43_wldev *dev, st
(q->free_packet_slots == 0)) {
/* The queue is full. */
ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
- q->stopped = 1;
+ q->stopped = true;
}
out:
@@ -601,7 +601,7 @@ void b43_pio_handle_txstatus(struct b43_
if (q->stopped) {
ieee80211_wake_queue(dev->wl->hw, q->queue_prio);
- q->stopped = 0;
+ q->stopped = false;
}
}
diff -u -p a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
--- a/drivers/net/wireless/b43/main.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/b43/main.c 2011-12-19 13:23:17.828434721 +1030
@@ -1122,17 +1122,17 @@ void b43_power_saving_ctl_bits(struct b4
B43_WARN_ON((ps_flags & B43_PS_AWAKE) && (ps_flags & B43_PS_ASLEEP));
if (ps_flags & B43_PS_ENABLED) {
- hwps = 1;
+ hwps = true;
} else if (ps_flags & B43_PS_DISABLED) {
- hwps = 0;
+ hwps = false;
} else {
//TODO: If powersave is not off and FIXME is not set and we are not in adhoc
// and thus is not an AP and we are associated, set bit 25
}
if (ps_flags & B43_PS_AWAKE) {
- awake = 1;
+ awake = true;
} else if (ps_flags & B43_PS_ASLEEP) {
- awake = 0;
+ awake = false;
} else {
//TODO: If the device is awake or this is an AP, or we are scanning, or FIXME,
// or we are associated, or FIXME, or the latest PS-Poll packet sent was
@@ -1140,8 +1140,8 @@ void b43_power_saving_ctl_bits(struct b4
}
/* FIXME: For now we force awake-on and hwps-off */
- hwps = 0;
- awake = 1;
+ hwps = false;
+ awake = true;
macctl = b43_read32(dev, B43_MMIO_MACCTL);
if (hwps)
@@ -1339,7 +1339,7 @@ static void b43_calculate_link_quality(s
return;
if (dev->noisecalc.calculation_running)
return;
- dev->noisecalc.calculation_running = 1;
+ dev->noisecalc.calculation_running = true;
dev->noisecalc.nr_samples = 0;
b43_generate_noise_sample(dev);
@@ -1408,7 +1408,7 @@ static void handle_irq_noise(struct b43_
average -= 48;
dev->stats.link_noise = average;
- dev->noisecalc.calculation_running = 0;
+ dev->noisecalc.calculation_running = false;
return;
}
generate_new:
@@ -1424,7 +1424,7 @@ static void handle_irq_tbtt_indication(s
b43_power_saving_ctl_bits(dev, 0);
}
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC))
- dev->dfq_valid = 1;
+ dev->dfq_valid = true;
}
static void handle_irq_atim_end(struct b43_wldev *dev)
@@ -1433,7 +1433,7 @@ static void handle_irq_atim_end(struct b
b43_write32(dev, B43_MMIO_MACCMD,
b43_read32(dev, B43_MMIO_MACCMD)
| B43_MACCMD_DFQ_VALID);
- dev->dfq_valid = 0;
+ dev->dfq_valid = false;
}
}
@@ -1539,7 +1539,7 @@ static void b43_write_beacon_template(st
unsigned int i, len, variable_len;
const struct ieee80211_mgmt *bcn;
const u8 *ie;
- bool tim_found = 0;
+ bool tim_found = false;
unsigned int rate;
u16 ctl;
int antenna;
@@ -1588,7 +1588,7 @@ static void b43_write_beacon_template(st
/* A valid TIM is at least 4 bytes long. */
if (ie_len < 4)
break;
- tim_found = 1;
+ tim_found = true;
tim_position = sizeof(struct b43_plcp_hdr6);
tim_position += offsetof(struct ieee80211_mgmt, u.beacon.variable);
@@ -1625,7 +1625,7 @@ static void b43_upload_beacon0(struct b4
if (wl->beacon0_uploaded)
return;
b43_write_beacon_template(dev, 0x68, 0x18);
- wl->beacon0_uploaded = 1;
+ wl->beacon0_uploaded = true;
}
static void b43_upload_beacon1(struct b43_wldev *dev)
@@ -1635,7 +1635,7 @@ static void b43_upload_beacon1(struct b4
if (wl->beacon1_uploaded)
return;
b43_write_beacon_template(dev, 0x468, 0x1A);
- wl->beacon1_uploaded = 1;
+ wl->beacon1_uploaded = true;
}
static void handle_irq_beacon(struct b43_wldev *dev)
@@ -1667,7 +1667,7 @@ static void handle_irq_beacon(struct b43
if (unlikely(wl->beacon_templates_virgin)) {
/* We never uploaded a beacon before.
* Upload both templates now, but only mark one valid. */
- wl->beacon_templates_virgin = 0;
+ wl->beacon_templates_virgin = false;
b43_upload_beacon0(dev);
b43_upload_beacon1(dev);
cmd = b43_read32(dev, B43_MMIO_MACCMD);
@@ -1755,8 +1755,8 @@ static void b43_update_templates(struct
if (wl->current_beacon)
dev_kfree_skb_any(wl->current_beacon);
wl->current_beacon = beacon;
- wl->beacon0_uploaded = 0;
- wl->beacon1_uploaded = 0;
+ wl->beacon0_uploaded = false;
+ wl->beacon1_uploaded = false;
ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
}
@@ -1913,7 +1913,7 @@ static void b43_do_interrupt_thread(stru
b43err(dev->wl, "This device does not support DMA "
"on your system. It will now be switched to PIO.\n");
/* Fall back to PIO transfers if we get fatal DMA errors! */
- dev->use_pio = 1;
+ dev->use_pio = true;
b43_controller_restart(dev, "DMA error");
return;
}
@@ -2240,12 +2240,12 @@ static int b43_try_request_fw(struct b43
filename = NULL;
else
goto err_no_pcm;
- fw->pcm_request_failed = 0;
+ fw->pcm_request_failed = false;
err = b43_do_request_fw(ctx, filename, &fw->pcm);
if (err == -ENOENT) {
/* We did not find a PCM file? Not fatal, but
* core rev <= 10 must do without hwcrypto then. */
- fw->pcm_request_failed = 1;
+ fw->pcm_request_failed = true;
} else if (err)
goto err_load;
@@ -2535,7 +2535,7 @@ static int b43_upload_microcode(struct b
dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues;
dev->qos_enabled = !!modparam_qos;
/* Default to firmware/hardware crypto acceleration. */
- dev->hwcrypto_enabled = 1;
+ dev->hwcrypto_enabled = true;
if (dev->fw.opensource) {
u16 fwcapa;
@@ -2549,7 +2549,7 @@ static int b43_upload_microcode(struct b
if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) {
b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n");
/* Disable hardware crypto and fall back to software crypto. */
- dev->hwcrypto_enabled = 0;
+ dev->hwcrypto_enabled = false;
}
if (!(fwcapa & B43_FWCAPA_QOS)) {
b43info(dev->wl, "QoS not supported by firmware\n");
@@ -2557,7 +2557,7 @@ static int b43_upload_microcode(struct b
* ieee80211_unregister to make sure the networking core can
* properly free possible resources. */
dev->wl->hw->queues = 1;
- dev->qos_enabled = 0;
+ dev->qos_enabled = false;
}
} else {
b43info(dev->wl, "Loading firmware version %u.%u "
@@ -3361,10 +3361,10 @@ static int b43_rng_init(struct b43_wl *w
wl->rng.name = wl->rng_name;
wl->rng.data_read = b43_rng_read;
wl->rng.priv = (unsigned long)wl;
- wl->rng_initialized = 1;
+ wl->rng_initialized = true;
err = hwrng_register(&wl->rng);
if (err) {
- wl->rng_initialized = 0;
+ wl->rng_initialized = false;
b43err(wl, "Failed to register the random "
"number generator (%d)\n", err);
}
@@ -3702,13 +3702,13 @@ static int b43_switch_band(struct b43_wl
case IEEE80211_BAND_5GHZ:
if (d->phy.supports_5ghz) {
up_dev = d;
- gmode = 0;
+ gmode = false;
}
break;
case IEEE80211_BAND_2GHZ:
if (d->phy.supports_2ghz) {
up_dev = d;
- gmode = 1;
+ gmode = true;
}
break;
default:
@@ -4425,18 +4425,18 @@ static void setup_struct_phy_for_init(st
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
#if B43_DEBUG
- phy->phy_locked = 0;
- phy->radio_locked = 0;
+ phy->phy_locked = false;
+ phy->radio_locked = false;
#endif
}
static void setup_struct_wldev_for_init(struct b43_wldev *dev)
{
- dev->dfq_valid = 0;
+ dev->dfq_valid = false;
/* Assume the radio is enabled. If it's not enabled, the state will
* immediately get fixed on the first periodic work run. */
- dev->radio_hw_enable = 1;
+ dev->radio_hw_enable = true;
/* Stats */
memset(&dev->stats, 0, sizeof(dev->stats));
@@ -4670,16 +4670,16 @@ static int b43_wireless_core_init(struct
if (b43_bus_host_is_pcmcia(dev->dev) ||
b43_bus_host_is_sdio(dev->dev)) {
- dev->__using_pio_transfers = 1;
+ dev->__using_pio_transfers = true;
err = b43_pio_init(dev);
} else if (dev->use_pio) {
b43warn(dev->wl, "Forced PIO by use_pio module parameter. "
"This should not be needed and will result in lower "
"performance.\n");
- dev->__using_pio_transfers = 1;
+ dev->__using_pio_transfers = true;
err = b43_pio_init(dev);
} else {
- dev->__using_pio_transfers = 0;
+ dev->__using_pio_transfers = false;
err = b43_dma_init(dev);
}
if (err)
@@ -4733,7 +4733,7 @@ static int b43_op_add_interface(struct i
b43dbg(wl, "Adding Interface type %d\n", vif->type);
dev = wl->current_dev;
- wl->operating = 1;
+ wl->operating = true;
wl->vif = vif;
wl->if_type = vif->type;
memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
@@ -4767,7 +4767,7 @@ static void b43_op_remove_interface(stru
B43_WARN_ON(wl->vif != vif);
wl->vif = NULL;
- wl->operating = 0;
+ wl->operating = false;
b43_adjust_opmode(dev);
memset(wl->mac_addr, 0, ETH_ALEN);
@@ -4789,12 +4789,12 @@ static int b43_op_start(struct ieee80211
memset(wl->bssid, 0, ETH_ALEN);
memset(wl->mac_addr, 0, ETH_ALEN);
wl->filter_flags = 0;
- wl->radiotap_enabled = 0;
+ wl->radiotap_enabled = false;
b43_qos_clear(wl);
- wl->beacon0_uploaded = 0;
- wl->beacon1_uploaded = 0;
- wl->beacon_templates_virgin = 1;
- wl->radio_enabled = 1;
+ wl->beacon0_uploaded = false;
+ wl->beacon1_uploaded = false;
+ wl->beacon_templates_virgin = true;
+ wl->radio_enabled = true;
mutex_lock(&wl->mutex);
@@ -4840,7 +4840,7 @@ static void b43_op_stop(struct ieee80211
goto out_unlock;
}
b43_wireless_core_exit(dev);
- wl->radio_enabled = 0;
+ wl->radio_enabled = false;
out_unlock:
mutex_unlock(&wl->mutex);
@@ -5028,7 +5028,7 @@ static int b43_wireless_core_attach(stru
struct pci_dev *pdev = NULL;
int err;
u32 tmp;
- bool have_2ghz_phy = 0, have_5ghz_phy = 0;
+ bool have_2ghz_phy = false, have_5ghz_phy = false;
/* Do NOT do any device initialization here.
* Do it in wireless_core_init() instead.
@@ -5071,7 +5071,7 @@ static int b43_wireless_core_attach(stru
}
dev->phy.gmode = have_2ghz_phy;
- dev->phy.radio_on = 1;
+ dev->phy.radio_on = true;
b43_wireless_core_reset(dev, dev->phy.gmode);
err = b43_phy_versioning(dev);
@@ -5082,11 +5082,11 @@ static int b43_wireless_core_attach(stru
(pdev->device != 0x4312 &&
pdev->device != 0x4319 && pdev->device != 0x4324)) {
/* No multiband support. */
- have_2ghz_phy = 0;
- have_5ghz_phy = 0;
+ have_2ghz_phy = false;
+ have_5ghz_phy = false;
switch (dev->phy.type) {
case B43_PHYTYPE_A:
- have_5ghz_phy = 1;
+ have_5ghz_phy = true;
break;
case B43_PHYTYPE_LP: //FIXME not always!
#if 0 //FIXME enabling 5GHz causes a NULL pointer dereference
@@ -5096,7 +5096,7 @@ static int b43_wireless_core_attach(stru
case B43_PHYTYPE_N:
case B43_PHYTYPE_HT:
case B43_PHYTYPE_LCN:
- have_2ghz_phy = 1;
+ have_2ghz_phy = true;
break;
default:
B43_WARN_ON(1);
@@ -5112,8 +5112,8 @@ static int b43_wireless_core_attach(stru
/* FIXME: For now we disable the A-PHY on multi-PHY devices. */
if (dev->phy.type != B43_PHYTYPE_N &&
dev->phy.type != B43_PHYTYPE_LP) {
- have_2ghz_phy = 1;
- have_5ghz_phy = 0;
+ have_2ghz_phy = true;
+ have_5ghz_phy = false;
}
}
diff -u -p a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
--- a/drivers/net/wireless/iwmc3200wifi/rx.c 2011-05-28 15:06:19.000000000 +0930
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c 2011-12-19 13:23:19.492434763 +1030
@@ -660,7 +660,7 @@ static int iwm_mlme_profile_invalidate(s
clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
- iwm->umac_profile_active = 0;
+ iwm->umac_profile_active = false;
memset(iwm->bssid, 0, ETH_ALEN);
iwm->channel = 0;
@@ -735,7 +735,7 @@ static int iwm_mlme_update_sta_table(str
umac_sta->mac_addr,
umac_sta->flags & UMAC_STA_FLAG_QOS);
- sta->valid = 1;
+ sta->valid = true;
sta->qos = umac_sta->flags & UMAC_STA_FLAG_QOS;
sta->color = GET_VAL8(umac_sta->sta_id, LMAC_STA_COLOR);
memcpy(sta->addr, umac_sta->mac_addr, ETH_ALEN);
@@ -750,12 +750,12 @@ static int iwm_mlme_update_sta_table(str
sta = &iwm->sta_table[GET_VAL8(umac_sta->sta_id, LMAC_STA_ID)];
if (!memcmp(sta->addr, umac_sta->mac_addr, ETH_ALEN))
- sta->valid = 0;
+ sta->valid = false;
break;
case UMAC_OPCODE_CLEAR_ALL:
for (i = 0; i < IWM_STA_TABLE_NUM; i++)
- iwm->sta_table[i].valid = 0;
+ iwm->sta_table[i].valid = false;
break;
default:
@@ -1203,7 +1203,7 @@ static int iwm_ntf_wifi_if_wrapper(struc
switch (hdr->oid) {
case UMAC_WIFI_IF_CMD_SET_PROFILE:
- iwm->umac_profile_active = 1;
+ iwm->umac_profile_active = true;
break;
default:
break;
@@ -1363,7 +1363,7 @@ static int iwm_rx_handle_nonwifi(struct
*/
list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending)
if (cmd->seq_num == seq_num) {
- cmd->resp_received = 1;
+ cmd->resp_received = true;
cmd->buf.len = buf_size;
memcpy(cmd->buf.hdr, buf, buf_size);
wake_up_interruptible(&iwm->nonwifi_queue);
diff -u -p a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
--- a/drivers/net/wireless/iwmc3200wifi/main.c 2011-12-19 13:09:30.712413542 +1030
+++ b/drivers/net/wireless/iwmc3200wifi/main.c 2011-12-19 13:23:19.900434774 +1030
@@ -130,7 +130,7 @@ static void iwm_disconnect_work(struct w
iwm_invalidate_mlme_profile(iwm);
clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
- iwm->umac_profile_active = 0;
+ iwm->umac_profile_active = false;
memset(iwm->bssid, 0, ETH_ALEN);
iwm->channel = 0;
diff -u -p a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
--- a/drivers/net/wireless/libertas/if_cs.c 2011-05-28 15:06:19.000000000 +0930
+++ b/drivers/net/wireless/libertas/if_cs.c 2011-12-19 13:23:21.148434806 +1030
@@ -859,7 +859,7 @@ static int if_cs_probe(struct pcmcia_dev
* Most of the libertas cards can do unaligned register access, but some
* weird ones cannot. That's especially true for the CF8305 card.
*/
- card->align_regs = 0;
+ card->align_regs = false;
card->model = get_model(p_dev->manf_id, p_dev->card_id);
if (card->model == MODEL_UNKNOWN) {
@@ -871,7 +871,7 @@ static int if_cs_probe(struct pcmcia_dev
/* Check if we have a current silicon */
prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
if (card->model == MODEL_8305) {
- card->align_regs = 1;
+ card->align_regs = true;
if (prod_id < IF_CS_CF8305_B1_REV) {
pr_err("8305 rev B0 and older are not supported\n");
ret = -ENODEV;
diff -u -p a/drivers/net/wireless/wl12xx/sdio_test.c b/drivers/net/wireless/wl12xx/sdio_test.c
--- a/drivers/net/wireless/wl12xx/sdio_test.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/wl12xx/sdio_test.c 2011-12-19 13:23:22.184434832 +1030
@@ -341,8 +341,8 @@ static int tester(void *data)
struct sdio_func *func = wl_to_func(wl);
struct device *pdev = &func->dev;
int ret = 0;
- bool rx_started = 0;
- bool tx_started = 0;
+ bool rx_started = false;
+ bool tx_started = false;
uint8_t *tx_buf, *rx_buf;
int test_size = PAGE_SIZE;
u32 addr = 0;
@@ -371,18 +371,18 @@ static int tester(void *data)
while (!kthread_should_stop()) {
if (rx && !rx_started) {
dev_info(pdev, "starting rx test\n");
- rx_started = 1;
+ rx_started = true;
} else if (!rx && rx_started) {
dev_info(pdev, "stopping rx test\n");
- rx_started = 0;
+ rx_started = false;
}
if (tx && !tx_started) {
dev_info(pdev, "starting tx test\n");
- tx_started = 1;
+ tx_started = true;
} else if (!tx && tx_started) {
dev_info(pdev, "stopping tx test\n");
- tx_started = 0;
+ tx_started = false;
}
if (rx_started)
diff -u -p a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c 2011-11-21 11:21:33.000000000 +1030
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c 2011-12-19 13:23:24.928434902 +1030
@@ -627,10 +627,10 @@ struct dma_pub *dma_attach(char *name, s
/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
if ((ai_coreid(sih) == SDIOD_CORE_ID)
&& ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
- di->addrext = 0;
+ di->addrext = false;
else if ((ai_coreid(sih) == I2S_CORE_ID) &&
((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
- di->addrext = 0;
+ di->addrext = false;
else
di->addrext = _dma_isaddrext(di);
diff -u -p a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c 2011-12-19 13:23:26.584434944 +1030
@@ -1603,7 +1603,7 @@ wlc_lcnphy_set_chanspec_tweaks(struct br
si_pmu_pllupd(pi->sh->sih);
write_phy_reg(pi, 0x942, 0);
wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
- pi_lcn->lcnphy_spurmod = 0;
+ pi_lcn->lcnphy_spurmod = false;
mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
write_phy_reg(pi, 0x425, 0x5907);
@@ -1616,7 +1616,7 @@ wlc_lcnphy_set_chanspec_tweaks(struct br
write_phy_reg(pi, 0x942, 0);
wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
- pi_lcn->lcnphy_spurmod = 0;
+ pi_lcn->lcnphy_spurmod = false;
mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
write_phy_reg(pi, 0x425, 0x590a);
@@ -2325,7 +2325,7 @@ static s8 wlc_lcnphy_tempcompensated_txp
{
s8 index, delta_brd, delta_temp, new_index, tempcorrx;
s16 manp, meas_temp, temp_diff;
- bool neg = 0;
+ bool neg = false;
u16 temp;
struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
@@ -2348,7 +2348,7 @@ static s8 wlc_lcnphy_tempcompensated_txp
manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
temp_diff = manp - meas_temp;
if (temp_diff < 0) {
- neg = 1;
+ neg = true;
temp_diff = -temp_diff;
}
@@ -3681,8 +3681,8 @@ wlc_lcnphy_a1(struct brcms_phy *pi, int
wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
udelay(20);
for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
- phy_c23 = 1;
- phy_c22 = 0;
+ phy_c23 = true;
+ phy_c22 = false;
switch (cal_type) {
case 0:
phy_c10 = 511;
@@ -3700,18 +3700,18 @@ wlc_lcnphy_a1(struct brcms_phy *pi, int
phy_c9 = read_phy_reg(pi, 0x93d);
phy_c9 = 2 * phy_c9;
- phy_c24 = 0;
+ phy_c24 = false;
phy_c5 = 7;
- phy_c25 = 1;
+ phy_c25 = true;
while (1) {
write_radio_reg(pi, RADIO_2064_REG026,
(phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
udelay(50);
- phy_c22 = 0;
+ phy_c22 = false;
ptr[130] = 0;
wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
if (ptr[130] == 1)
- phy_c22 = 1;
+ phy_c22 = true;
if (phy_c22)
phy_c5 -= 1;
if ((phy_c22 != phy_c24) && (!phy_c25))
@@ -3721,7 +3721,7 @@ wlc_lcnphy_a1(struct brcms_phy *pi, int
if (phy_c5 <= 0 || phy_c5 >= 7)
break;
phy_c24 = phy_c22;
- phy_c25 = 0;
+ phy_c25 = false;
}
if (phy_c5 < 0)
@@ -3772,10 +3772,10 @@ wlc_lcnphy_a1(struct brcms_phy *pi, int
phy_c13 = phy_c11;
phy_c14 = phy_c12;
}
- phy_c23 = 0;
+ phy_c23 = false;
}
}
- phy_c23 = 1;
+ phy_c23 = true;
phy_c15 = phy_c13;
phy_c16 = phy_c14;
phy_c7 = phy_c7 >> 1;
@@ -3965,7 +3965,7 @@ s16 wlc_lcnphy_tempsense_new(struct brcm
{
u16 tempsenseval1, tempsenseval2;
s16 avg = 0;
- bool suspend = 0;
+ bool suspend = false;
if (mode == 1) {
suspend =
@@ -4007,7 +4007,7 @@ u16 wlc_lcnphy_tempsense(struct brcms_ph
{
u16 tempsenseval1, tempsenseval2;
s32 avg = 0;
- bool suspend = 0;
+ bool suspend = false;
u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
@@ -4075,7 +4075,7 @@ s8 wlc_lcnphy_vbatsense(struct brcms_phy
{
u16 vbatsenseval;
s32 avg = 0;
- bool suspend = 0;
+ bool suspend = false;
if (mode == 1) {
suspend =
diff -u -p a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2011-12-19 13:23:39.144435266 +1030
@@ -1332,7 +1332,7 @@ uint brcms_reset(struct brcms_info *wl)
brcms_c_reset(wl->wlc);
/* dpc will not be rescheduled */
- wl->resched = 0;
+ wl->resched = false;
return 0;
}
diff -u -p a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2011-12-19 13:23:42.196435345 +1030
@@ -845,7 +845,7 @@ static int brcmf_netdev_stop(struct net_
return 0;
/* Set state and stop OS transmissions */
- drvr->up = 0;
+ drvr->up = false;
netif_stop_queue(ndev);
return 0;
@@ -884,7 +884,7 @@ static int brcmf_netdev_open(struct net_
}
/* Allow transmit calls */
netif_start_queue(ndev);
- drvr_priv->pub.up = 1;
+ drvr_priv->pub.up = true;
if (brcmf_cfg80211_up(drvr_priv->pub.config)) {
brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
return -1;
diff -u -p a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
--- a/drivers/net/wireless/mwl8k.c 2011-12-19 13:09:30.716413542 +1030
+++ b/drivers/net/wireless/mwl8k.c 2011-12-19 13:23:44.756435410 +1030
@@ -738,10 +738,10 @@ static int mwl8k_load_firmware(struct ie
ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
if (ready_code == MWL8K_FWAP_READY) {
- priv->ap_fw = 1;
+ priv->ap_fw = true;
break;
} else if (ready_code == MWL8K_FWSTA_READY) {
- priv->ap_fw = 0;
+ priv->ap_fw = false;
break;
}
@@ -5517,8 +5517,8 @@ static int mwl8k_firmware_load_success(s
INIT_LIST_HEAD(&priv->vif_list);
/* Set default radio state and preamble */
- priv->radio_on = 0;
- priv->radio_short_preamble = 0;
+ priv->radio_on = false;
+ priv->radio_short_preamble = false;
/* Finalize join worker */
INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
diff -u -p a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c 2011-10-27 10:37:52.000000000 +1030
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c 2011-12-19 13:23:50.220435550 +1030
@@ -1381,7 +1381,7 @@ static void __iwl_down(struct iwl_priv *
/* reset BT coex data */
priv->bt_status = 0;
priv->cur_rssi_ctx = NULL;
- priv->bt_is_sco = 0;
+ priv->bt_is_sco = false;
if (priv->cfg->bt_params)
priv->bt_traffic_load =
priv->cfg->bt_params->bt_init_traffic_load;
diff -u -p a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
--- a/drivers/net/wireless/mac80211_hwsim.c 2011-11-07 15:50:48.000000000 +1030
+++ b/drivers/net/wireless/mac80211_hwsim.c 2011-12-19 13:23:52.012435595 +1030
@@ -707,7 +707,7 @@ static int mac80211_hwsim_start(struct i
{
struct mac80211_hwsim_data *data = hw->priv;
wiphy_debug(hw->wiphy, "%s\n", __func__);
- data->started = 1;
+ data->started = true;
return 0;
}
@@ -715,7 +715,7 @@ static int mac80211_hwsim_start(struct i
static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
{
struct mac80211_hwsim_data *data = hw->priv;
- data->started = 0;
+ data->started = false;
del_timer(&data->beacon_timer);
wiphy_debug(hw->wiphy, "%s\n", __func__);
}
diff -u -p a/net/dccp/options.c b/net/dccp/options.c
--- a/net/dccp/options.c 2011-05-19 15:03:22.000000000 +0930
+++ b/net/dccp/options.c 2011-12-19 13:29:33.116444329 +1030
@@ -544,7 +544,7 @@ int dccp_insert_fn_opt(struct sk_buff *s
}
if (unlikely(val == NULL || len == 0))
- len = repeat_first = 0;
+ len = repeat_first = false;
tot_len = 3 + repeat_first + len;
if (DCCP_SKB_CB(skb)->dccpd_opt_len + tot_len > DCCP_MAX_OPT_LEN) {
diff -u -p a/net/dccp/feat.c b/net/dccp/feat.c
--- a/net/dccp/feat.c 2011-10-27 10:37:55.000000000 +1030
+++ b/net/dccp/feat.c 2011-12-19 13:29:33.576444342 +1030
@@ -490,8 +490,8 @@ static int dccp_feat_push_change(struct
new->feat_num = feat;
new->is_local = local;
new->state = FEAT_INITIALISING;
- new->needs_confirm = 0;
- new->empty_confirm = 0;
+ new->needs_confirm = false;
+ new->empty_confirm = false;
new->val = *fval;
new->needs_mandatory = mandatory;
@@ -517,12 +517,12 @@ static int dccp_feat_push_confirm(struct
new->feat_num = feat;
new->is_local = local;
new->state = FEAT_STABLE; /* transition in 6.6.2 */
- new->needs_confirm = 1;
+ new->needs_confirm = true;
new->empty_confirm = (fval == NULL);
new->val.nn = 0; /* zeroes the whole structure */
if (!new->empty_confirm)
new->val = *fval;
- new->needs_mandatory = 0;
+ new->needs_mandatory = false;
return 0;
}
@@ -1155,7 +1155,7 @@ static u8 dccp_feat_change_recv(struct l
}
if (dccp_feat_reconcile(&entry->val, val, len, server, true)) {
- entry->empty_confirm = 0;
+ entry->empty_confirm = false;
} else if (is_mandatory) {
return DCCP_RESET_CODE_MANDATORY_ERROR;
} else if (entry->state == FEAT_INITIALISING) {
@@ -1171,10 +1171,10 @@ static u8 dccp_feat_change_recv(struct l
defval = dccp_feat_default_value(feat);
if (!dccp_feat_reconcile(&entry->val, &defval, 1, server, true))
return DCCP_RESET_CODE_OPTION_ERROR;
- entry->empty_confirm = 1;
+ entry->empty_confirm = true;
}
- entry->needs_confirm = 1;
- entry->needs_mandatory = 0;
+ entry->needs_confirm = true;
+ entry->needs_mandatory = false;
entry->state = FEAT_STABLE;
return 0;
diff -u -p a/net/mac80211/scan.c b/net/mac80211/scan.c
--- a/net/mac80211/scan.c 2011-11-07 15:50:48.000000000 +1030
+++ b/net/mac80211/scan.c 2011-12-19 13:29:39.276444488 +1030
@@ -106,7 +106,7 @@ ieee80211_bss_info_update(struct ieee802
/* save the ERP value so that it is available at association time */
if (elems->erp_info && elems->erp_info_len >= 1) {
bss->erp_value = elems->erp_info[0];
- bss->has_erp_value = 1;
+ bss->has_erp_value = true;
}
if (elems->tim) {
diff -u -p a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
--- a/net/mac80211/rc80211_pid_algo.c 2010-08-23 11:46:56.000000000 +0930
+++ b/net/mac80211/rc80211_pid_algo.c 2011-12-19 13:29:40.776444526 +1030
@@ -318,7 +318,7 @@ rate_control_pid_rate_init(void *priv, s
rinfo[i].diff = i * pinfo->norm_offset;
}
for (i = 1; i < sband->n_bitrates; i++) {
- s = 0;
+ s = false;
for (j = 0; j < sband->n_bitrates - i; j++)
if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
sband->bitrates[rinfo[j + 1].index].bitrate)) {
@@ -327,7 +327,7 @@ rate_control_pid_rate_init(void *priv, s
rinfo[j + 1].index = tmp;
rinfo[rinfo[j].index].rev_index = j;
rinfo[rinfo[j + 1].index].rev_index = j + 1;
- s = 1;
+ s = true;
}
if (!s)
break;
diff -u -p a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c
--- a/net/netfilter/ipvs/ip_vs_pe_sip.c 2011-03-31 12:06:06.000000000 +1030
+++ b/net/netfilter/ipvs/ip_vs_pe_sip.c 2011-12-19 13:29:43.564444597 +1030
@@ -108,7 +108,7 @@ static bool ip_vs_sip_ct_match(const str
struct ip_vs_conn *ct)
{
- bool ret = 0;
+ bool ret = false;
if (ct->af == p->af &&
ip_vs_addr_equal(p->af, p->caddr, &ct->caddr) &&
@@ -121,7 +121,7 @@ static bool ip_vs_sip_ct_match(const str
ct->protocol == p->protocol &&
ct->pe_data && ct->pe_data_len == p->pe_data_len &&
!memcmp(ct->pe_data, p->pe_data, p->pe_data_len))
- ret = 1;
+ ret = true;
IP_VS_DBG_BUF(9, "SIP template match %s %s->%s:%d %s\n",
ip_vs_proto_name(p->protocol),
diff -u -p a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
--- a/net/ipv4/tcp_timer.c 2011-10-27 10:37:55.000000000 +1030
+++ b/net/ipv4/tcp_timer.c 2011-12-19 13:29:52.944444838 +1030
@@ -171,13 +171,13 @@ static int tcp_write_timeout(struct sock
{
struct inet_connection_sock *icsk = inet_csk(sk);
int retry_until;
- bool do_reset, syn_set = 0;
+ bool do_reset, syn_set = false;
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
if (icsk->icsk_retransmits)
dst_negative_advice(sk);
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
- syn_set = 1;
+ syn_set = true;
} else {
if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) {
/* Black hole detection */
diff -u -p a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c
--- a/net/rfkill/rfkill-regulator.c 2011-10-27 10:37:55.000000000 +1030
+++ b/net/rfkill/rfkill-regulator.c 2011-12-19 13:29:59.740445012 +1030
@@ -36,12 +36,12 @@ static int rfkill_regulator_set_block(vo
if (blocked) {
if (rfkill_data->reg_enabled) {
regulator_disable(rfkill_data->vcc);
- rfkill_data->reg_enabled = 0;
+ rfkill_data->reg_enabled = false;
}
} else {
if (!rfkill_data->reg_enabled) {
regulator_enable(rfkill_data->vcc);
- rfkill_data->reg_enabled = 1;
+ rfkill_data->reg_enabled = true;
}
}
@@ -96,7 +96,7 @@ static int __devinit rfkill_regulator_pr
if (regulator_is_enabled(vcc)) {
dev_dbg(&pdev->dev, "Regulator already enabled\n");
- rfkill_data->reg_enabled = 1;
+ rfkill_data->reg_enabled = true;
}
rfkill_data->vcc = vcc;
rfkill_data->rf_kill = rf_kill;
diff -u -p a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c
--- a/net/rxrpc/ar-ack.c 2011-05-28 15:06:24.000000000 +0930
+++ b/net/rxrpc/ar-ack.c 2011-12-19 13:30:05.168445151 +1030
@@ -195,7 +195,7 @@ static void rxrpc_resend(struct rxrpc_ca
sp = rxrpc_skb(txb);
if (sp->need_resend) {
- sp->need_resend = 0;
+ sp->need_resend = false;
/* each Tx packet has a new serial number */
sp->hdr.serial =
@@ -216,7 +216,7 @@ static void rxrpc_resend(struct rxrpc_ca
}
if (time_after_eq(jiffies + 1, sp->resend_at)) {
- sp->need_resend = 1;
+ sp->need_resend = true;
resend |= 1;
} else if (resend & 2) {
if (time_before(sp->resend_at, resend_at))
@@ -265,7 +265,7 @@ static void rxrpc_resend_timer(struct rx
if (sp->need_resend) {
;
} else if (time_after_eq(jiffies + 1, sp->resend_at)) {
- sp->need_resend = 1;
+ sp->need_resend = true;
resend |= 1;
} else if (resend & 2) {
if (time_before(sp->resend_at, resend_at))
@@ -314,11 +314,11 @@ static int rxrpc_process_soft_ACKs(struc
switch (sacks[loop]) {
case RXRPC_ACK_TYPE_ACK:
- sp->need_resend = 0;
+ sp->need_resend = false;
*p_txb |= 1;
break;
case RXRPC_ACK_TYPE_NACK:
- sp->need_resend = 1;
+ sp->need_resend = true;
*p_txb &= ~1;
resend = 1;
break;
@@ -344,13 +344,13 @@ static int rxrpc_process_soft_ACKs(struc
if (*p_txb & 1) {
/* packet must have been discarded */
- sp->need_resend = 1;
+ sp->need_resend = true;
*p_txb &= ~1;
resend |= 1;
} else if (sp->need_resend) {
;
} else if (time_after_eq(jiffies + 1, sp->resend_at)) {
- sp->need_resend = 1;
+ sp->need_resend = true;
resend |= 1;
} else if (resend & 2) {
if (time_before(sp->resend_at, resend_at))
diff -u -p a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c
--- a/net/rxrpc/ar-output.c 2011-11-07 15:50:48.000000000 +1030
+++ b/net/rxrpc/ar-output.c 2011-12-19 13:30:05.452445157 +1030
@@ -486,7 +486,7 @@ static void rxrpc_queue_packet(struct rx
_proto("Tx DATA %%%u { #%u }",
ntohl(sp->hdr.serial), ntohl(sp->hdr.seq));
- sp->need_resend = 0;
+ sp->need_resend = false;
sp->resend_at = jiffies + rxrpc_resend_timeout * HZ;
if (!test_and_set_bit(RXRPC_CALL_RUN_RTIMER, &call->flags)) {
_debug("run timer");
@@ -508,7 +508,7 @@ static void rxrpc_queue_packet(struct rx
if (ret < 0) {
_debug("need instant resend %d", ret);
- sp->need_resend = 1;
+ sp->need_resend = true;
rxrpc_instant_resend(call);
}
^ permalink raw reply
* [PATCH] stmmac: reduce queue lengths if MTU is very large
From: Giuseppe CAVALLARO @ 2011-12-19 5:45 UTC (permalink / raw)
To: netdev; +Cc: rubini, giancarlo.asnaghi
From: Alessandro Rubini <rubini@gnudd.com>
In my use case (STA2X11 IO-Hub), the alloc_coherent, map_single and
friends map to a reserved area set up in swiotlb. With the default
MTU each packet takes 2kB, but with jumbo frames it increases to 16kB
and consumes up my area (it takes 8MB instead of 1MB).
Instead of increasing the reserved (== wasted) preallocated area in
swiotlb, this patch rescales the user-selected queue lengths if the MTU
is modified at runtime to be larger than the default. User choices
are still obeyed (compiled default, module parameter, command line)
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Acked-by: Giancarlo Asnaghi <giancarlo.asnaghi@st.com>
Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 72cd190..e8ebb6e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -413,9 +413,8 @@ static void init_dma_desc_rings(struct net_device *dev)
int i;
struct stmmac_priv *priv = netdev_priv(dev);
struct sk_buff *skb;
- unsigned int txsize = priv->dma_tx_size;
- unsigned int rxsize = priv->dma_rx_size;
- unsigned int bfsize;
+ unsigned int txsize, rxsize;
+ unsigned int bfsize = priv->dma_buf_sz;
int dis_ic = 0;
int des3_as_data_buf = 0;
@@ -428,6 +427,20 @@ static void init_dma_desc_rings(struct net_device *dev)
else
bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
+ /*
+ * If we use jumbo frames, we end up consuming too much memory
+ * in the coherent buffer, so reduce the queue lenght according
+ * to the increase in frame size over the default.
+ */
+ i = bfsize / BUF_SIZE_2KiB;
+ if (i > 1) {
+ pr_warning("%s: reducing queue length by %i\n", __func__, i);
+ priv->dma_tx_size /= i;
+ priv->dma_rx_size /= i;
+ }
+ txsize = priv->dma_tx_size;
+ rxsize = priv->dma_rx_size;
+
#ifdef CONFIG_STMMAC_TIMER
/* Disable interrupts on completion for the reception if timer is on */
if (likely(priv->tm->enable))
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH 14/15] module_param: make bool parameters really bool (net & drivers/net)
From: Rusty Russell @ 2011-12-19 5:49 UTC (permalink / raw)
To: David Miller; +Cc: joe, linux-kernel, pawel.moll, netdev
In-Reply-To: <20111215.231517.185391590658983405.davem@davemloft.net>
On Thu, 15 Dec 2011 23:15:17 -0500 (EST), David Miller <davem@davemloft.net> wrote:
> From: Rusty Russell <rusty@rustcorp.com.au>
> Date: Fri, 16 Dec 2011 09:44:31 +1030
>
> > Dave, did you want a true/false cleanup too?
>
> Please, this kind of stuff rots forever and not using bool properly
> drives me crazy.
And here's the updated patch:
From: Rusty Russell <rusty@rustcorp.com.au>
Subject: module_param: make bool parameters really bool (net & drivers/net)
module_param(bool) used to counter-intuitively take an int. In
fddd5201 (mid-2009) we allowed bool or int/unsigned int using a messy
trick.
It's time to remove the int/unsigned int option. For this version
it'll simply give a warning, but it'll break next kernel version.
(Thanks to Joe Perches for suggesting coccinelle for 0/1 -> true/false).
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
drivers/net/caif/caif_serial.c | 6 +++---
drivers/net/caif/caif_spi.c | 2 +-
drivers/net/can/vcan.c | 2 +-
drivers/net/ethernet/amd/amd8111e.h | 4 ++--
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 +-
drivers/net/ethernet/dlink/de600.c | 2 +-
drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +-
drivers/net/ethernet/mellanox/mlx4/main.c | 2 +-
drivers/net/ethernet/via/via-rhine.c | 5 +++--
drivers/net/irda/donauboe.c | 2 +-
drivers/net/irda/smsc-ircc2.c | 2 +-
drivers/net/usb/pegasus.c | 4 ++--
drivers/net/usb/smsc75xx.c | 2 +-
drivers/net/usb/smsc95xx.c | 2 +-
drivers/net/virtio_net.c | 2 +-
drivers/net/wan/sbni.c | 2 +-
drivers/net/wan/sealevel.c | 2 +-
drivers/net/wireless/ath/ath5k/ath5k.h | 2 +-
drivers/net/wireless/ath/ath5k/base.c | 6 +++---
drivers/net/wireless/ath/carl9170/main.c | 2 +-
drivers/net/wireless/iwmc3200wifi/main.c | 4 ++--
drivers/net/wireless/mwl8k.c | 2 +-
drivers/net/wireless/orinoco/main.c | 2 +-
drivers/net/wireless/p54/main.c | 2 +-
drivers/net/wireless/rt2x00/rt2500usb.c | 2 +-
drivers/net/wireless/rt2x00/rt2800pci.c | 2 +-
drivers/net/wireless/rt2x00/rt2800usb.c | 2 +-
drivers/net/wireless/rt2x00/rt61pci.c | 2 +-
drivers/net/wireless/rt2x00/rt73usb.c | 2 +-
drivers/net/wireless/rtlwifi/wifi.h | 2 +-
include/net/bluetooth/l2cap.h | 2 +-
include/net/sctp/structs.h | 2 +-
net/bluetooth/bnep/core.c | 4 ++--
net/bluetooth/hci_event.c | 2 +-
net/bluetooth/hci_sock.c | 2 +-
net/bluetooth/l2cap_core.c | 2 +-
net/bluetooth/rfcomm/core.c | 4 ++--
net/bluetooth/sco.c | 2 +-
net/dccp/ccids/ccid2.c | 4 ++--
net/dccp/ccids/ccid3.c | 2 +-
net/dccp/ccids/lib/tfrc.c | 2 +-
net/dccp/ccids/lib/tfrc.h | 2 +-
net/dccp/dccp.h | 2 +-
net/dccp/proto.c | 2 +-
net/ipv4/netfilter/ipt_ULOG.c | 2 +-
net/ipv4/netfilter/iptable_filter.c | 2 +-
net/ipv6/netfilter/ip6table_filter.c | 2 +-
net/irda/irlan/irlan_common.c | 2 +-
net/netfilter/nf_conntrack_acct.c | 2 +-
net/netfilter/nf_conntrack_ftp.c | 2 +-
net/netfilter/nf_conntrack_h323_main.c | 2 +-
net/netfilter/nf_conntrack_timestamp.c | 2 +-
52 files changed, 64 insertions(+), 63 deletions(-)
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
--- a/drivers/net/caif/caif_serial.c
+++ b/drivers/net/caif/caif_serial.c
@@ -38,15 +38,15 @@ MODULE_ALIAS_LDISC(N_CAIF);
/*This list is protected by the rtnl lock. */
static LIST_HEAD(ser_list);
-static int ser_loop;
+static bool ser_loop;
module_param(ser_loop, bool, S_IRUGO);
MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode.");
-static int ser_use_stx = 1;
+static bool ser_use_stx = true;
module_param(ser_use_stx, bool, S_IRUGO);
MODULE_PARM_DESC(ser_use_stx, "STX enabled or not.");
-static int ser_use_fcs = 1;
+static bool ser_use_fcs = true;
module_param(ser_use_fcs, bool, S_IRUGO);
MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not.");
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("CAIF SPI driver");
/* Returns the number of padding bytes for alignment. */
#define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1)))))
-static int spi_loop;
+static bool spi_loop;
module_param(spi_loop, bool, S_IRUGO);
MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode.");
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -63,7 +63,7 @@ MODULE_AUTHOR("Urs Thuermann <urs.thuerm
* See Documentation/networking/can.txt for details.
*/
-static int echo; /* echo testing. Default: 0 (Off) */
+static bool echo; /* echo testing. Default: 0 (Off) */
module_param(echo, bool, S_IRUGO);
MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
diff --git a/drivers/net/ethernet/amd/amd8111e.h b/drivers/net/ethernet/amd/amd8111e.h
--- a/drivers/net/ethernet/amd/amd8111e.h
+++ b/drivers/net/ethernet/amd/amd8111e.h
@@ -808,8 +808,8 @@ typedef enum {
static int card_idx;
static int speed_duplex[MAX_UNITS] = { 0, };
-static int coalesce[MAX_UNITS] = {1,1,1,1,1,1,1,1};
-static int dynamic_ipg[MAX_UNITS] = {0,0,0,0,0,0,0,0};
+static bool coalesce[MAX_UNITS] = {1,1,1,1,1,1,1,1};
+static bool dynamic_ipg[MAX_UNITS] = {0,0,0,0,0,0,0,0};
static unsigned int chip_version;
#endif /* _AMD8111E_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -243,7 +243,7 @@ module_param_array(intr_cnt, uint, NULL,
MODULE_PARM_DESC(intr_cnt,
"thresholds 1..3 for queue interrupt packet counters");
-static int vf_acls;
+static bool vf_acls;
#ifdef CONFIG_PCI_IOV
module_param(vf_acls, bool, 0644);
diff --git a/drivers/net/ethernet/dlink/de600.c b/drivers/net/ethernet/dlink/de600.c
--- a/drivers/net/ethernet/dlink/de600.c
+++ b/drivers/net/ethernet/dlink/de600.c
@@ -59,7 +59,7 @@ static const char version[] = "de600.c:
#include "de600.h"
-static unsigned int check_lost = 1;
+static bool check_lost = true;
module_param(check_lost, bool, 0);
MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -48,7 +48,7 @@ enum {
extern void __buggy_use_of_MLX4_GET(void);
extern void __buggy_use_of_MLX4_PUT(void);
-static int enable_qos;
+static bool enable_qos;
module_param(enable_qos, bool, 0444);
MODULE_PARM_DESC(enable_qos, "Enable Quality of Service support in the HCA (default: off)");
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -99,7 +99,7 @@ MODULE_PARM_DESC(log_num_vlan, "Log2 max
/* Log2 max number of VLANs per ETH port (0-7) */
#define MLX4_LOG_NUM_VLANS 7
-static int use_prio;
+static bool use_prio;
module_param_named(use_prio, use_prio, bool, 0444);
MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
"(0/1, default 0)");
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -35,6 +35,7 @@
#define DRV_VERSION "1.5.0"
#define DRV_RELDATE "2010-10-09"
+#include <linux/types.h>
/* A few user-configurable values.
These may be modified when a driver module is loaded. */
@@ -55,7 +56,7 @@ static int rx_copybreak;
/* Work-around for broken BIOSes: they are unable to get the chip back out of
power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
-static int avoid_D3;
+static bool avoid_D3;
/*
* In case you are looking for 'options[]' or 'full_duplex[]', they
@@ -2320,7 +2321,7 @@ static int __init rhine_init(void)
#endif
if (dmi_check_system(rhine_dmi_table)) {
/* these BIOSes fail at PXE boot if chip is in D3 */
- avoid_D3 = 1;
+ avoid_D3 = true;
pr_warn("Broken BIOS detected, avoid_D3 enabled\n");
}
else if (avoid_D3)
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -197,7 +197,7 @@ static char *driver_name = DRIVER_NAME;
static int max_baud = 4000000;
#ifdef USE_PROBE
-static int do_probe = 0;
+static bool do_probe = false;
#endif
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -79,7 +79,7 @@ MODULE_AUTHOR("Daniele Peri <peri@csai.u
MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver");
MODULE_LICENSE("GPL");
-static int smsc_nopnp = 1;
+static bool smsc_nopnp = true;
module_param_named(nopnp, smsc_nopnp, bool, 0);
MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings, defaults to true");
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -55,8 +55,8 @@ static const char driver_name[] = "pegas
#define BMSR_MEDIA (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \
BMSR_100FULL | BMSR_ANEGCAPABLE)
-static int loopback;
-static int mii_mode;
+static bool loopback;
+static bool mii_mode;
static char *devid;
static struct usb_eth_dev usb_dev_id[] = {
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -76,7 +76,7 @@ struct usb_context {
struct usbnet *dev;
};
-static int turbo_mode = true;
+static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -59,7 +59,7 @@ struct usb_context {
struct usbnet *dev;
};
-static int turbo_mode = true;
+static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -30,7 +30,7 @@
static int napi_weight = 128;
module_param(napi_weight, int, 0444);
-static int csum = 1, gso = 1;
+static bool csum = true, gso = true;
module_param(csum, bool, 0444);
module_param(gso, bool, 0444);
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -155,7 +155,7 @@ static int emancipate( struct net_devic
static const char version[] =
"Granch SBNI12 driver ver 5.0.1 Jun 22 2001 Denis I.Timofeev.\n";
-static int skip_pci_probe __initdata = 0;
+static bool skip_pci_probe __initdata = false;
static int scandone __initdata = 0;
static int num __initdata = 0;
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -362,7 +362,7 @@ static int io=0x238;
static int txdma=1;
static int rxdma=3;
static int irq=5;
-static int slow=0;
+static bool slow=false;
module_param(io, int, 0);
MODULE_PARM_DESC(io, "The I/O base of the Sealevel card");
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -747,7 +747,7 @@ struct ath5k_athchan_2ghz {
*/
#define AR5K_KEYCACHE_SIZE 8
-extern int ath5k_modparam_nohwcrypt;
+extern bool ath5k_modparam_nohwcrypt;
/***********************\
HW RELATED DEFINITIONS
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -68,15 +68,15 @@
#define CREATE_TRACE_POINTS
#include "trace.h"
-int ath5k_modparam_nohwcrypt;
+bool ath5k_modparam_nohwcrypt;
module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-static int modparam_all_channels;
+static bool modparam_all_channels;
module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
-static int modparam_fastchanswitch;
+static bool modparam_fastchanswitch;
module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -48,7 +48,7 @@
#include "carl9170.h"
#include "cmd.h"
-static int modparam_nohwcrypt;
+static bool modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload.");
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -91,11 +91,11 @@ static struct iwm_conf def_iwm_conf = {
.mac_addr = {0x00, 0x02, 0xb3, 0x01, 0x02, 0x03},
};
-static int modparam_reset;
+static bool modparam_reset;
module_param_named(reset, modparam_reset, bool, 0644);
MODULE_PARM_DESC(reset, "reset on firmware errors (default 0 [not reset])");
-static int modparam_wimax_enable = 1;
+static bool modparam_wimax_enable = true;
module_param_named(wimax_enable, modparam_wimax_enable, bool, 0644);
MODULE_PARM_DESC(wimax_enable, "Enable wimax core (default 1 [wimax enabled])");
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -31,7 +31,7 @@
#define MWL8K_VERSION "0.12"
/* Module parameters */
-static unsigned ap_mode_default;
+static bool ap_mode_default;
module_param(ap_mode_default, bool, 0);
MODULE_PARM_DESC(ap_mode_default,
"Set to 1 to make ap mode the default instead of sta mode");
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -121,7 +121,7 @@ module_param(orinoco_debug, int, 0644);
MODULE_PARM_DESC(orinoco_debug, "Debug level");
#endif
-static int suppress_linkstatus; /* = 0 */
+static bool suppress_linkstatus; /* = 0 */
module_param(suppress_linkstatus, bool, 0644);
MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -27,7 +27,7 @@
#include "p54.h"
#include "lmac.h"
-static int modparam_nohwcrypt;
+static bool modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -39,7 +39,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt;
+static bool modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -50,7 +50,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static bool modparam_nohwcrypt = false;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -45,7 +45,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt;
+static bool modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -41,7 +41,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt = 0;
+static bool modparam_nohwcrypt = false;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -40,7 +40,7 @@
/*
* Allow hardware encryption to be disabled.
*/
-static int modparam_nohwcrypt;
+static bool modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1485,7 +1485,7 @@ struct rtl_intf_ops {
struct rtl_mod_params {
/* default: 0 = using hardware encryption */
- int sw_crypto;
+ bool sw_crypto;
/* default: 0 = DBG_EMERG (0)*/
int debug;
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -492,7 +492,7 @@ static inline int l2cap_tx_window_full(s
#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE)
#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
-extern int disable_ertm;
+extern bool disable_ertm;
int l2cap_init_sockets(void);
void l2cap_cleanup_sockets(void);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -235,7 +235,7 @@ extern struct sctp_globals {
/* Flag to indicate whether computing and verifying checksum
* is disabled. */
- int checksum_disable;
+ bool checksum_disable;
/* Threshold for rwnd update SACKS. Receive buffer shifted this many
* bits is an indicator of when to send and window update SACK.
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -56,8 +56,8 @@
#define VERSION "1.3"
-static int compress_src = 1;
-static int compress_dst = 1;
+static bool compress_src = true;
+static bool compress_dst = true;
static LIST_HEAD(bnep_session_list);
static DECLARE_RWSEM(bnep_session_sem);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -45,7 +45,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-static int enable_le;
+static bool enable_le;
/* Handle HCI Event packets */
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -49,7 +49,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-static int enable_mgmt;
+static bool enable_mgmt;
/* ----- HCI socket interface ----- */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -56,7 +56,7 @@
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h>
-int disable_ertm;
+bool disable_ertm;
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
static u8 l2cap_fixed_chan[8] = { 0x02, };
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -51,8 +51,8 @@
#define VERSION "1.11"
-static int disable_cfc;
-static int l2cap_ertm;
+static bool disable_cfc;
+static bool l2cap_ertm;
static int channel_mtu = -1;
static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -51,7 +51,7 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/sco.h>
-static int disable_esco;
+static bool disable_esco;
static const struct proto_ops sco_sock_ops;
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -29,7 +29,7 @@
#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
-static int ccid2_debug;
+static bool ccid2_debug;
#define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a)
#else
#define ccid2_pr_debug(format, a...)
@@ -174,7 +174,7 @@ out:
/*
* Congestion window validation (RFC 2861).
*/
-static int ccid2_do_cwv = 1;
+static bool ccid2_do_cwv = true;
module_param(ccid2_do_cwv, bool, 0644);
MODULE_PARM_DESC(ccid2_do_cwv, "Perform RFC2861 Congestion Window Validation");
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -38,7 +38,7 @@
#include <asm/unaligned.h>
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
-static int ccid3_debug;
+static bool ccid3_debug;
#define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
#else
#define ccid3_pr_debug(format, a...)
diff --git a/net/dccp/ccids/lib/tfrc.c b/net/dccp/ccids/lib/tfrc.c
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -8,7 +8,7 @@
#include "tfrc.h"
#ifdef CONFIG_IP_DCCP_TFRC_DEBUG
-int tfrc_debug;
+bool tfrc_debug;
module_param(tfrc_debug, bool, 0644);
MODULE_PARM_DESC(tfrc_debug, "Enable TFRC debug messages");
#endif
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -21,7 +21,7 @@
#include "packet_history.h"
#ifdef CONFIG_IP_DCCP_TFRC_DEBUG
-extern int tfrc_debug;
+extern bool tfrc_debug;
#define tfrc_pr_debug(format, a...) DCCP_PR_DEBUG(tfrc_debug, format, ##a)
#else
#define tfrc_pr_debug(format, a...)
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -39,7 +39,7 @@
"%s: " fmt, __func__, ##a)
#ifdef CONFIG_IP_DCCP_DEBUG
-extern int dccp_debug;
+extern bool dccp_debug;
#define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
#define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
#define dccp_debug(fmt, a...) dccp_pr_debug_cat(KERN_DEBUG fmt, ##a)
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1099,7 +1099,7 @@ module_param(thash_entries, int, 0444);
MODULE_PARM_DESC(thash_entries, "Number of ehash buckets");
#ifdef CONFIG_IP_DCCP_DEBUG
-int dccp_debug;
+bool dccp_debug;
module_param(dccp_debug, bool, 0644);
MODULE_PARM_DESC(dccp_debug, "Enable debug messages");
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -65,7 +65,7 @@ static unsigned int flushtimeout = 10;
module_param(flushtimeout, uint, 0600);
MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)");
-static int nflog = 1;
+static bool nflog = true;
module_param(nflog, bool, 0400);
MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -52,7 +52,7 @@ iptable_filter_hook(unsigned int hook, s
static struct nf_hook_ops *filter_ops __read_mostly;
/* Default to forward because I got too much mail already. */
-static int forward = NF_ACCEPT;
+static bool forward = NF_ACCEPT;
module_param(forward, bool, 0000);
static int __net_init iptable_filter_net_init(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -44,7 +44,7 @@ ip6table_filter_hook(unsigned int hook,
static struct nf_hook_ops *filter_ops __read_mostly;
/* Default to forward because I got too much mail already. */
-static int forward = NF_ACCEPT;
+static bool forward = NF_ACCEPT;
module_param(forward, bool, 0000);
static int __net_init ip6table_filter_net_init(struct net *net)
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -67,7 +67,7 @@ static void *ckey;
static void *skey;
/* Module parameters */
-static int eth; /* Use "eth" or "irlan" name for devices */
+static bool eth; /* Use "eth" or "irlan" name for devices */
static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
#ifdef CONFIG_PROC_FS
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -18,7 +18,7 @@
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_acct.h>
-static int nf_ct_acct __read_mostly;
+static bool nf_ct_acct __read_mostly;
module_param_named(acct, nf_ct_acct, bool, 0644);
MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting.");
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -42,7 +42,7 @@ static u_int16_t ports[MAX_PORTS];
static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
-static int loose;
+static bool loose;
module_param(loose, bool, 0600);
unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -42,7 +42,7 @@ static int gkrouted_only __read_mostly =
module_param(gkrouted_only, int, 0600);
MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");
-static int callforward_filter __read_mostly = 1;
+static bool callforward_filter __read_mostly = true;
module_param(callforward_filter, bool, 0600);
MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations "
"if both endpoints are on different sides "
diff --git a/net/netfilter/nf_conntrack_timestamp.c b/net/netfilter/nf_conntrack_timestamp.c
--- a/net/netfilter/nf_conntrack_timestamp.c
+++ b/net/netfilter/nf_conntrack_timestamp.c
@@ -15,7 +15,7 @@
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_timestamp.h>
-static int nf_ct_tstamp __read_mostly;
+static bool nf_ct_tstamp __read_mostly;
module_param_named(tstamp, nf_ct_tstamp, bool, 0644);
MODULE_PARM_DESC(tstamp, "Enable connection tracking flow timestamping.");
^ permalink raw reply
* Re: [PATCH 14/15] module_param: make bool parameters really bool (net & drivers/net)
From: Joe Perches @ 2011-12-19 6:42 UTC (permalink / raw)
To: Rusty Russell; +Cc: David Miller, linux-kernel, pawel.moll, netdev
In-Reply-To: <87ehw1nm9r.fsf@rustcorp.com.au>
On Mon, 2011-12-19 at 16:19 +1030, Rusty Russell wrote:
> diff --git a/drivers/net/ethernet/amd/amd8111e.h b/drivers/net/ethernet/amd/amd8111e.h
[]
> @@ -808,8 +808,8 @@ typedef enum {
[]
> +static bool coalesce[MAX_UNITS] = {1,1,1,1,1,1,1,1};
> +static bool dynamic_ipg[MAX_UNITS] = {0,0,0,0,0,0,0,0};
Perhaps these array initializations could/should be:
static bool coalesce[MAX_UNITS] = { [0 ... MAX_UNITS - 1] = true };
static bool dynamic_irq[MAX_UNITS] = { [0 ... MAX_UNITS - 1] = false };
in a separate patch maybe.
^ permalink raw reply
* [PATCH v2] ARM: net: JIT compiler for packet filters
From: Mircea Gherzan @ 2011-12-19 8:40 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: mgherzan, netdev
Based of Matt Evans's PPC64 implementation.
Supports only ARM mode with EABI.
Supports both little and big endian. Depends on the support for
unaligned loads on ARMv7. Does not support all the BPF opcodes
that deal with ancillary data. The scratch memory of the filter
lives on the stack.
Enabled in the same way as for x86-64 and PPC64:
echo 1 > /proc/sys/net/core/bpf_jit_enable
A value greater than 1 enables opcode output.
Signed-off-by: Mircea Gherzan <mgherzan@gmail.com>
---
Changes in v2:
* enable the compiler ony for ARMv5+ because of the BLX instruction
* use the same comparison for the ARM version checks
* use misaligned accesses on ARMv6
* fix the SEEN_MEM
* fix the mem_words_used()
arch/arm/Kconfig | 1 +
arch/arm/Makefile | 1 +
arch/arm/net/Makefile | 3 +
arch/arm/net/bpf_jit_32.c | 838 +++++++++++++++++++++++++++++++++++++++++++++
arch/arm/net/bpf_jit_32.h | 174 ++++++++++
5 files changed, 1017 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/net/Makefile
create mode 100644 arch/arm/net/bpf_jit_32.c
create mode 100644 arch/arm/net/bpf_jit_32.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index abba5b8..ea65c41 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -30,6 +30,7 @@ config ARM
select HAVE_SPARSE_IRQ
select GENERIC_IRQ_SHOW
select CPU_PM if (SUSPEND || CPU_IDLE)
+ select HAVE_BPF_JIT if (!THUMB2_KERNEL && AEABI)
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index dfcf3b0..8810a10 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -255,6 +255,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y += arch/arm/net/
core-y += $(machdirs) $(platdirs)
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile
new file mode 100644
index 0000000..c2c1084
--- /dev/null
+++ b/arch/arm/net/Makefile
@@ -0,0 +1,3 @@
+# ARM-specific networking code
+
+obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
new file mode 100644
index 0000000..d2b86fa
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.c
@@ -0,0 +1,838 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/compiler.h>
+#include <linux/filter.h>
+#include <linux/moduleloader.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+
+#include "bpf_jit_32.h"
+
+/* BLX is available on ARMv5 or higher */
+#if __LINUX_ARM_ARCH__ < 5
+# error "The BPF JIT compiler is only available on ARMv5 or higher!"
+#endif
+
+/*
+ * ABI:
+ *
+ * r0 scratch register
+ * r4 BPF register A
+ * r5 BPF register X
+ * r6 pointer to the skb
+ * r7 skb->data
+ * r8 skb_headlen(skb)
+ */
+
+#define r_scratch ARM_R0
+/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */
+#define r_off ARM_R1
+#define r_A ARM_R4
+#define r_X ARM_R5
+#define r_skb ARM_R6
+#define r_skb_data ARM_R7
+#define r_skb_hl ARM_R8
+
+#define SCRATCH_SP_OFFSET 0
+#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k))
+
+#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1)
+#define SEEN_MEM_WORD(k) (1 << (k))
+#define SEEN_X (1 << BPF_MEMWORDS)
+#define SEEN_CALL (1 << (BPF_MEMWORDS + 1))
+#define SEEN_DATA (1 << (BPF_MEMWORDS + 2))
+#define SEEN_LEN (1 << (BPF_MEMWORDS + 3))
+
+struct jit_ctx {
+ const struct sk_filter *skf;
+ unsigned idx;
+ unsigned prologue_bytes;
+ int ret0_fp_idx;
+ u32 seen;
+ u32 *offsets;
+ u32 *target;
+#if __LINUX_ARM_ARCH__ < 7
+ u16 epilogue_bytes;
+ u16 imm_count;
+ u32 *imms;
+#endif
+};
+
+int bpf_jit_enable __read_mostly;
+
+static u8 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
+{
+ u8 ret;
+ skb_copy_bits(skb, offset, &ret, 1);
+ return ret;
+}
+
+static u16 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
+{
+ u16 ret;
+ skb_copy_bits(skb, offset, &ret, 2);
+ return ntohs(ret);
+}
+
+static u32 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
+{
+ u32 ret;
+ skb_copy_bits(skb, offset, &ret, 4);
+ return ntohl(ret);
+}
+
+static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
+{
+ if (ctx->target != NULL)
+ ctx->target[ctx->idx] = inst | (cond << 28);
+
+ ctx->idx++;
+}
+
+/*
+ * Emit an instruction that will be executed unconditionally.
+ */
+static inline void emit(u32 inst, struct jit_ctx *ctx)
+{
+ _emit(ARM_COND_AL, inst, ctx);
+}
+
+static u16 saved_regs(struct jit_ctx *ctx)
+{
+ u16 ret = 0;
+
+ if (ctx->skf->len > 1)
+ ret |= 1 << r_A;
+
+#ifdef CONFIG_FRAME_POINTER
+ ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC);
+#else
+ if (ctx->seen & SEEN_CALL)
+ ret |= 1 << ARM_LR;
+#endif
+ if (ctx->seen & (SEEN_DATA | SEEN_LEN))
+ ret |= 1 << r_skb;
+ if (ctx->seen & SEEN_DATA)
+ ret |= (1 << r_skb_data) | (1 << r_skb_hl);
+ if (ctx->seen & SEEN_X)
+ ret |= 1 << r_X;
+
+ return ret;
+}
+
+static inline int mem_words_used(struct jit_ctx *ctx)
+{
+ u32 words = ctx->seen & SEEN_MEM;
+ /* yes, we do waste some stack space IF there are "holes" in the set" */
+ return 32 - __builtin_clz(words);
+}
+
+static inline bool is_load_to_a(u16 inst)
+{
+ switch (inst) {
+ case BPF_S_LD_W_LEN:
+ case BPF_S_LD_W_ABS:
+ case BPF_S_LD_H_ABS:
+ case BPF_S_LD_B_ABS:
+ case BPF_S_ANC_CPU:
+ case BPF_S_ANC_IFINDEX:
+ case BPF_S_ANC_MARK:
+ case BPF_S_ANC_PROTOCOL:
+ case BPF_S_ANC_RXHASH:
+ case BPF_S_ANC_QUEUE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static void build_prologue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+ u16 first_inst = ctx->skf->insns[0].code;
+ u16 off;
+
+#ifdef CONFIG_FRAME_POINTER
+ emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx);
+ emit(ARM_PUSH(reg_set), ctx);
+ emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx);
+#else
+ if (reg_set)
+ emit(ARM_PUSH(reg_set), ctx);
+#endif
+
+ if (ctx->seen & (SEEN_DATA | SEEN_LEN))
+ emit(ARM_MOV_R(r_skb, ARM_R0), ctx);
+
+ if (ctx->seen & SEEN_DATA) {
+ off = offsetof(struct sk_buff, data);
+ emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx);
+ /* headlen = len - data_len */
+ off = offsetof(struct sk_buff, len);
+ emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx);
+ off = offsetof(struct sk_buff, data_len);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+ emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx);
+ }
+
+ if (ctx->seen & SEEN_X)
+ emit(ARM_MOV_I(r_X, 0), ctx);
+
+ /* do not leak kernel data to userspace */
+ if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst)))
+ emit(ARM_MOV_I(r_A, 0), ctx);
+
+ /* stack space for the BPF_MEM words */
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+}
+
+static void build_epilogue(struct jit_ctx *ctx)
+{
+ u16 reg_set = saved_regs(ctx);
+
+ if (ctx->seen & SEEN_MEM)
+ emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx);
+
+ reg_set &= ~(1 << ARM_LR);
+
+#ifdef CONFIG_FRAME_POINTER
+ /* the first instruction of the prologue was: mov ip, sp */
+ reg_set &= ~(1 << ARM_IP);
+ reg_set |= (1 << ARM_SP);
+ emit(ARM_LDM(ARM_SP, reg_set), ctx);
+#else
+ if (ctx->seen)
+ emit(ARM_POP(reg_set | (1 << ARM_PC)), ctx);
+ else
+ emit(ARM_BX(ARM_LR), ctx);
+#endif
+}
+
+static int16_t imm8m(u32 x)
+{
+ u32 rot;
+
+ for (rot = 0; rot < 16; rot++)
+ if ((x & ~ror32(0xff, 2 * rot)) == 0)
+ return rol32(x, 2 * rot) | (rot << 8);
+
+ return -1;
+}
+
+#if __LINUX_ARM_ARCH__ < 7
+
+static u16 imm_offset(u32 k, struct jit_ctx *ctx)
+{
+ unsigned i = 0, offset;
+ u16 imm;
+
+ /* on the "fake" run we just count them (duplicates included) */
+ if (ctx->target == NULL) {
+ ctx->imm_count++;
+ return 0;
+ }
+
+ while ((i < ctx->imm_count) && ctx->imms[i]) {
+ if (ctx->imms[i] == k)
+ break;
+ i++;
+ }
+
+ if (ctx->imms[i] == 0)
+ ctx->imms[i] = k;
+
+ /* constants go just after the epilogue */
+ offset = ctx->offsets[ctx->skf->len];
+ offset += ctx->prologue_bytes;
+ offset += ctx->epilogue_bytes;
+ offset += i * 4;
+
+ ctx->target[offset / 4] = k;
+
+ /* PC in ARM mode == address of the instruction + 8 */
+ imm = offset - (8 + ctx->idx * 4);
+
+ return imm;
+}
+
+#endif /* __LINUX_ARM_ARCH__ */
+
+/*
+ * Move an immediate that's not an imm8m to a core register.
+ */
+static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx)
+{
+#if __LINUX_ARM_ARCH__ < 7
+ emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx);
+#else
+ emit(ARM_MOVW(rd, val & 0xffff), ctx);
+ if (val > 0xffff)
+ emit(ARM_MOVT(rd, val >> 16), ctx);
+#endif
+}
+
+static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx)
+{
+ int imm12 = imm8m(val);
+
+ if (imm12 >= 0)
+ emit(ARM_MOV_I(rd, imm12), ctx);
+ else
+ emit_mov_i_no8m(rd, val, ctx);
+}
+
+#if __LINUX_ARM_ARCH__ < 6
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx);
+ _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx);
+ _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx);
+ _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx);
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx);
+ _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx);
+ _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx);
+}
+
+static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx)
+{
+ emit(ARM_LSL_R(ARM_R1, r_src, 8), ctx);
+ emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSL, 8), ctx);
+ emit(ARM_LSL_I(r_dst, r_dst, 8), ctx);
+ emit(ARM_LSL_R(r_dst, r_dst, 8), ctx);
+}
+
+#else /* ARMv6+ */
+
+static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV(r_res, r_res), ctx);
+#endif
+}
+
+static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx)
+{
+ _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx);
+#ifdef __LITTLE_ENDIAN
+ _emit(cond, ARM_REV16(r_res, r_res), ctx);
+#endif
+}
+
+static inline void emit_swap16(u8 r_dst __maybe_unused,
+ u8 r_src __maybe_unused,
+ struct jit_ctx *ctx __maybe_unused)
+{
+#ifdef __LITTLE_ENDIAN
+ emit(ARM_REV16(r_dst, r_src), ctx);
+#endif
+}
+
+#endif /* __LINUX_ARM_ARCH__ < 6 */
+
+
+/* Compute the immediate value for a PC-relative branch. */
+static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx)
+{
+ u32 imm;
+
+ if (ctx->target == NULL)
+ return 0;
+ /*
+ * BPF allows only forward jumps and the offset of the target is
+ * still the one computed during the first pass.
+ */
+ imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8);
+
+ return imm >> 2;
+}
+
+#define OP_IMM3(op, r1, r2, imm_val, ctx) \
+ do { \
+ imm12 = imm8m(imm_val); \
+ if (imm12 < 0) { \
+ emit_mov_i_no8m(r_scratch, imm_val, ctx); \
+ emit(op ## _R((r1), (r2), r_scratch), ctx); \
+ } else { \
+ emit(op ## _I((r1), (r2), imm12), ctx); \
+ } \
+ } while (0)
+
+static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx)
+{
+ if (ctx->ret0_fp_idx >= 0) {
+ _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx);
+ /* NOP to keep the size constant between passes */
+ emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx);
+ } else {
+ _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx);
+ _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx);
+ }
+}
+
+static int build_body(struct jit_ctx *ctx)
+{
+ void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
+ const struct sk_filter *prog = ctx->skf;
+ const struct sock_filter *inst;
+ unsigned i, load_order, off, condt, condf;
+ int imm12;
+ u32 k;
+
+ for (i = 0; i < prog->len; i++) {
+ inst = &(prog->insns[i]);
+ /* K as an immediate value operand */
+ k = inst->k;
+
+ /* compute offsets only in the fake pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ switch (inst->code) {
+ case BPF_S_LD_IMM:
+ emit_mov_i(r_A, k, ctx);
+ break;
+ case BPF_S_LD_W_LEN:
+ ctx->seen |= SEEN_LEN;
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+ emit(ARM_LDR_I(r_A, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_S_LD_MEM:
+ /* A = scratch[k] */
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_LD_W_ABS:
+ load_order = 2;
+ goto load;
+ case BPF_S_LD_H_ABS:
+ load_order = 1;
+ goto load;
+ case BPF_S_LD_B_ABS:
+ load_order = 0;
+load:
+ emit_mov_i(r_off, k, ctx);
+load_common:
+ ctx->seen |= SEEN_DATA | SEEN_CALL;
+
+ if (load_order > 0) {
+ emit(ARM_SUB_I(r_scratch, r_skb_hl,
+ 1 << load_order), ctx);
+ emit(ARM_CMP_R(r_scratch, r_off), ctx);
+ condt = ARM_COND_HS;
+ } else {
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+ condt = ARM_COND_HI;
+ }
+
+ _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
+ ctx);
+
+ if (load_order == 0)
+ _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0),
+ ctx);
+ else if (load_order == 1)
+ emit_load_be16(condt, r_A, r_scratch, ctx);
+ else if (load_order == 2)
+ emit_load_be32(condt, r_A, r_scratch, ctx);
+
+ _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx);
+
+ /* the slowpath */
+ emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx);
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* the offset is already in R1 */
+ emit(ARM_BLX_R(ARM_R3), ctx);
+ emit(ARM_MOV_R(r_A, ARM_R0), ctx);
+ break;
+ case BPF_S_LD_W_IND:
+ load_order = 2;
+ goto load_ind;
+ case BPF_S_LD_H_IND:
+ load_order = 1;
+ goto load_ind;
+ case BPF_S_LD_B_IND:
+ load_order = 0;
+load_ind:
+ OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
+ goto load_common;
+ case BPF_S_LDX_IMM:
+ ctx->seen |= SEEN_X;
+ emit_mov_i(r_X, k, ctx);
+ break;
+ case BPF_S_LDX_W_LEN:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LDR_I(r_X, r_skb,
+ offsetof(struct sk_buff, len)), ctx);
+ break;
+ case BPF_S_LDX_MEM:
+ ctx->seen |= SEEN_X | SEEN_MEM_WORD(k);
+ emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_LDX_B_MSH:
+ /* x = ((*(frame + k)) & 0xf) << 2; */
+ ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL;
+ /* offset in r1: we might have to take the slow path */
+ emit_mov_i(r_off, k, ctx);
+ emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
+
+ /* load in r0: common with the slowpath */
+ _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data,
+ ARM_R1), ctx);
+ _emit(ARM_COND_HI, ARM_B((3 * 4 - 8) >> 2), ctx);
+
+ emit(ARM_MOV_R(ARM_R0, r_skb), ctx);
+ /* r_off is r1 */
+ emit(ARM_MOV_I(ARM_R3, (u32)jit_get_skb_b), ctx);
+ emit(ARM_BLX_R(ARM_R3), ctx);
+
+ emit(ARM_ORR_I(r_X, ARM_R0, 0x00f), ctx);
+ emit(ARM_LSL_I(r_X, r_X, 2), ctx);
+ break;
+ case BPF_S_ST:
+ ctx->seen |= SEEN_MEM_WORD(k);
+ emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_STX:
+ ctx->seen |= SEEN_MEM_WORD(k) | SEEN_X;
+ emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx);
+ break;
+ case BPF_S_ALU_ADD_K:
+ /* A += K */
+ OP_IMM3(ARM_ADD, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_ADD_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_ADD_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_SUB_K:
+ /* A -= K */
+ OP_IMM3(ARM_SUB, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_SUB_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_SUB_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_MUL_K:
+ /* A *= K */
+ emit_mov_i(r_scratch, k, ctx);
+ emit(ARM_MUL(r_A, r_A, r_scratch), ctx);
+ break;
+ case BPF_S_ALU_MUL_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_MUL(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_DIV_K:
+ /* K is not zero, it was previously checked */
+ emit_mov_i(ARM_R1, k, ctx);
+ goto div;
+ case BPF_S_ALU_DIV_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_CMP_I(r_X, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+ emit(ARM_MOV_R(ARM_R1, r_X), ctx);
+div:
+ ctx->seen |= SEEN_CALL;
+
+ emit(ARM_MOV_R(ARM_R0, r_A), ctx);
+ emit_mov_i(r_scratch, (u32)__aeabi_uidiv, ctx);
+ emit(ARM_BLX_R(r_scratch), ctx);
+ emit(ARM_MOV_R(r_A, ARM_R0), ctx);
+ break;
+ case BPF_S_ALU_OR_K:
+ /* A |= K */
+ OP_IMM3(ARM_ORR, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_OR_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_ORR_I(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_AND_K:
+ /* A &= K */
+ OP_IMM3(ARM_AND, r_A, r_A, k, ctx);
+ break;
+ case BPF_S_ALU_AND_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_AND_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_LSH_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSL_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_S_ALU_LSH_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LSL_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_ALU_RSH_K:
+ if (unlikely(k > 31))
+ return -1;
+ emit(ARM_LSR_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_S_ALU_RSH_X:
+ ctx->seen |= SEEN_X;
+ emit(ARM_LSR_R(r_A, r_A, r_X), ctx);
+ break;
+ case BPF_S_JMP_JA:
+ /* pc += K */
+ emit(ARM_B(b_imm(i + k, ctx)), ctx);
+ break;
+ case BPF_S_JMP_JEQ_K:
+ /* pc += (A == K) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ condf = ARM_COND_NE;
+ goto cmp_imm;
+ case BPF_S_JMP_JGT_K:
+ /* pc += (A > K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ goto cmp_imm;
+ case BPF_S_JMP_JGE_K:
+ /* pc += (A >= K) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ /* (x >= y) IFF (x > y - 1) */
+ if (unlikely(k == 0))
+ return -1;
+ k--;
+cmp_imm:
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_CMP_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_CMP_I(r_A, imm12), ctx);
+ }
+cond_jump:
+ if (inst->jt)
+ _emit(condt, ARM_B(b_imm(i + inst->jt + 1,
+ ctx)), ctx);
+ if (inst->jf)
+ _emit(condf, ARM_B(b_imm(i + inst->jf + 1,
+ ctx)), ctx);
+ break;
+ case BPF_S_JMP_JEQ_X:
+ /* pc += (A == X) ? pc->jt : pc->jf */
+ condt = ARM_COND_EQ;
+ condf = ARM_COND_NE;
+ goto cmp_x;
+ case BPF_S_JMP_JGT_X:
+ /* pc += (A > X) ? pc->jt : pc->jf */
+ condt = ARM_COND_HI;
+ condf = ARM_COND_LS;
+ goto cmp_x;
+ case BPF_S_JMP_JGE_X:
+ /* pc += (A >= X) ? pc->jt : pc->jf */
+ condt = ARM_COND_CS;
+ condf = ARM_COND_CC;
+cmp_x:
+ ctx->seen |= SEEN_X;
+ emit(ARM_CMP_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_S_JMP_JSET_K:
+ /* pc += (A & K) ? pc->jt : pc->jf */
+ condt = ARM_COND_NE;
+ /* not set iff all zeroes iff Z==1 iff EQ */
+ condf = ARM_COND_EQ;
+
+ imm12 = imm8m(k);
+ if (imm12 < 0) {
+ emit_mov_i_no8m(r_scratch, k, ctx);
+ emit(ARM_TST_R(r_A, r_scratch), ctx);
+ } else {
+ emit(ARM_TST_I(r_A, imm12), ctx);
+ }
+ goto cond_jump;
+ case BPF_S_JMP_JSET_X:
+ /* pc += (A & X) ? pc->jt : pc->jf */
+ condt = ARM_COND_NE;
+ condf = ARM_COND_EQ;
+ emit(ARM_TST_R(r_A, r_X), ctx);
+ goto cond_jump;
+ case BPF_S_RET_A:
+ emit(ARM_MOV_R(ARM_R0, r_A), ctx);
+ goto b_epilogue;
+ case BPF_S_RET_K:
+ if ((k == 0) && (ctx->ret0_fp_idx < 0))
+ ctx->ret0_fp_idx = i;
+ emit_mov_i(ARM_R0, k, ctx);
+b_epilogue:
+ if (i != ctx->skf->len - 1)
+ emit(ARM_B(b_imm(prog->len, ctx)), ctx);
+ break;
+ case BPF_S_MISC_TAX:
+ /* X = A */
+ emit(ARM_MOV_R(r_X, r_A), ctx);
+ break;
+ case BPF_S_MISC_TXA:
+ /* A = X */
+ emit(ARM_MOV_R(r_A, r_X), ctx);
+ break;
+ case BPF_S_ANC_PROTOCOL:
+ /* A = ntohs(skb->protocol) */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ protocol) != 2);
+ off = offsetof(struct sk_buff, protocol);
+ emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx);
+ emit_swap16(r_A, r_scratch, ctx);
+ break;
+ case BPF_S_ANC_CPU:
+ /* A = current_thread_info()->cpu */
+ emit_mov_i(r_scratch, (~(THREAD_SIZE - 1)), ctx);
+ emit(ARM_ADD_R(r_scratch, ARM_SP, r_scratch), ctx);
+
+ BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4);
+ off = offsetof(struct thread_info, cpu);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_S_ANC_IFINDEX:
+ /* A = skb->dev->ifindex */
+ off = offsetof(struct sk_buff, dev);
+ emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
+
+ emit(ARM_CMP_I(r_scratch, 0), ctx);
+ emit_err_ret(ARM_COND_EQ, ctx);
+
+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
+ ifindex) != 4);
+ off = offsetof(struct net_device, ifindex);
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
+ break;
+ case BPF_S_ANC_MARK:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+ off = offsetof(struct sk_buff, mark);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_S_ANC_RXHASH:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
+ off = offsetof(struct sk_buff, rxhash);
+ emit(ARM_LDR_I(r_A, r_skb, off), ctx);
+ break;
+ case BPF_S_ANC_QUEUE:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ queue_mapping) != 2);
+ BUILD_BUG_ON(offsetof(struct sk_buff,
+ queue_mapping) > 0xff);
+ off = offsetof(struct sk_buff, queue_mapping);
+ emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ /* compute offsets only during the first pass */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ return 0;
+}
+
+
+void bpf_jit_compile(struct sk_filter *fp)
+{
+ struct jit_ctx ctx;
+ unsigned tmp_idx;
+ unsigned alloc_size;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.skf = fp;
+ ctx.ret0_fp_idx = -1;
+
+ ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1));
+ if (ctx.offsets == NULL)
+ return;
+
+ /* fake pass to fill in the ctx->seen */
+ if (unlikely(build_body(&ctx)))
+ goto out;
+
+ tmp_idx = ctx.idx;
+ build_prologue(&ctx);
+ ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4;
+
+#if __LINUX_ARM_ARCH__ < 7
+ tmp_idx = ctx.idx;
+ build_epilogue(&ctx);
+ ctx.epilogue_bytes = (ctx.idx - tmp_idx) * 4;
+
+ ctx.idx += ctx.imm_count;
+ if (ctx.imm_count) {
+ ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count);
+ if (ctx.imms == NULL)
+ goto out;
+ }
+#else
+ /* there's nothing after the epilogue on ARMv7 */
+ build_epilogue(&ctx);
+#endif
+
+ alloc_size = 4 * ctx.idx;
+ ctx.target = module_alloc(alloc_size > sizeof(struct work_struct) ?
+ alloc_size : sizeof(struct work_struct));
+ if (unlikely(ctx.target == NULL))
+ goto out;
+
+ ctx.idx = 0;
+ build_prologue(&ctx);
+ build_body(&ctx);
+ build_epilogue(&ctx);
+
+ flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
+
+#if __LINUX_ARM_ARCH__ < 7
+ if (ctx.imm_count)
+ kfree(ctx.imms);
+#endif
+
+ if (bpf_jit_enable > 1)
+ print_hex_dump(KERN_INFO, "BPF JIT code: ",
+ DUMP_PREFIX_ADDRESS, 16, 4, ctx.target,
+ alloc_size, false);
+
+ fp->bpf_func = (void *)ctx.target;
+
+out:
+ kfree(ctx.offsets);
+ return;
+}
+
+static void bpf_jit_free_worker(struct work_struct *work)
+{
+ module_free(NULL, work);
+}
+
+void bpf_jit_free(struct sk_filter *fp)
+{
+ struct work_struct *work;
+
+ if (fp->bpf_func != sk_run_filter) {
+ work = (struct work_struct *)fp->bpf_func;
+
+ INIT_WORK(work, bpf_jit_free_worker);
+ schedule_work(work);
+ }
+}
+
diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h
new file mode 100644
index 0000000..de68a51
--- /dev/null
+++ b/arch/arm/net/bpf_jit_32.h
@@ -0,0 +1,174 @@
+/*
+ * Just-In-Time compiler for BPF filters on 32bit ARM
+ *
+ * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#ifndef PFILTER_OPCODES_ARM_H
+#define PFILTER_OPCODES_ARM_H
+
+extern void *__aeabi_uidiv;
+
+#define ARM_R0 0
+#define ARM_R1 1
+#define ARM_R2 2
+#define ARM_R3 3
+#define ARM_R4 4
+#define ARM_R5 5
+#define ARM_R6 6
+#define ARM_R7 7
+#define ARM_R8 8
+#define ARM_R9 9
+#define ARM_R10 10
+#define ARM_FP 11
+#define ARM_IP 12
+#define ARM_SP 13
+#define ARM_LR 14
+#define ARM_PC 15
+
+#define ARM_COND_EQ 0x0
+#define ARM_COND_NE 0x1
+#define ARM_COND_CS 0x2
+#define ARM_COND_HS ARM_COND_CS
+#define ARM_COND_CC 0x3
+#define ARM_COND_LO ARM_COND_CC
+#define ARM_COND_MI 0x4
+#define ARM_COND_PL 0x5
+#define ARM_COND_VS 0x6
+#define ARM_COND_VC 0x7
+#define ARM_COND_HI 0x8
+#define ARM_COND_LS 0x9
+#define ARM_COND_GE 0xa
+#define ARM_COND_LT 0xb
+#define ARM_COND_GT 0xc
+#define ARM_COND_LE 0xd
+#define ARM_COND_AL 0xe
+
+/* register shift types */
+#define SRTYPE_LSL 0
+#define SRTYPE_LSR 1
+#define SRTYPE_ASR 2
+#define SRTYPE_ROR 3
+
+#define ARM_INST_ADD_R 0x00800000
+#define ARM_INST_ADD_I 0x02800000
+
+#define ARM_INST_AND_R 0x00000000
+#define ARM_INST_AND_I 0x02000000
+
+#define ARM_INST_B 0x0a000000
+#define ARM_INST_BX 0x012FFF10
+#define ARM_INST_BLX_R 0x012fff30
+
+#define ARM_INST_CMP_R 0x01500000
+#define ARM_INST_CMP_I 0x03500000
+
+#define ARM_INST_LDRB_I 0x05d00000
+#define ARM_INST_LDRB_R 0x07d00000
+#define ARM_INST_LDRH_I 0x01d000b0
+#define ARM_INST_LDR_I 0x05900000
+
+#define ARM_INST_LDM 0x08900000
+
+#define ARM_INST_LSL_I 0x01a00000
+#define ARM_INST_LSL_R 0x01a00010
+
+#define ARM_INST_LSR_I 0x01a00020
+#define ARM_INST_LSR_R 0x01a00030
+
+#define ARM_INST_MOV_R 0x01a00000
+#define ARM_INST_MOV_I 0x03a00000
+#define ARM_INST_MOVW 0x03000000
+#define ARM_INST_MOVT 0x03400000
+
+#define ARM_INST_MUL 0x00000090
+
+#define ARM_INST_POP 0x08bd0000
+#define ARM_INST_PUSH 0x092d0000
+
+#define ARM_INST_REV 0x06bf0f30
+#define ARM_INST_REV16 0x06bf0fb0
+
+#define ARM_INST_ORR_R 0x01800000
+#define ARM_INST_ORR_I 0x03800000
+
+#define ARM_INST_SUB_R 0x00400000
+#define ARM_INST_SUB_I 0x02400000
+
+#define ARM_INST_STR_I 0x05800000
+
+#define ARM_INST_TST_R 0x01100000
+#define ARM_INST_TST_I 0x03100000
+
+
+/* register */
+#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm))
+/* immediate */
+#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm))
+
+#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm)
+#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm)
+
+#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm)
+#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm)
+
+#define ARM_B(imm24) (ARM_INST_B | (imm24))
+#define ARM_BX(rm) (ARM_INST_BX | (rm))
+#define ARM_BLX_R(rm) (ARM_INST_BLX_R | (rm))
+
+#define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm)
+#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm)
+
+#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \
+ | (rm))
+#define ARM_LDRH_I(rt, rn, off) (ARM_INST_LDRH_I | (rt) << 12 | (rn) << 16 \
+ | (((off) & 0xf0) << 4) | ((off) & 0xf))
+
+#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs))
+
+#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8)
+#define ARM_LSL_I(rd, rn, imm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (imm) << 7)
+
+#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8)
+#define ARM_LSR_I(rd, rn, imm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (imm) << 7)
+
+#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm)
+#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm)
+
+#define ARM_MOVW(rd, imm) \
+ (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MOVT(rd, imm) \
+ (ARM_INST_MOVT | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
+
+#define ARM_MUL(rd, rm, rn) (ARM_INST_MUL | (rd) << 16 | (rm) << 8 | (rn))
+
+#define ARM_POP(regs) (ARM_INST_POP | (regs))
+#define ARM_PUSH(regs) (ARM_INST_PUSH | (regs))
+
+#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm)
+#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm)
+#define ARM_ORR_S(rd, rn, rm, type, rs) \
+ (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7)
+
+#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm))
+#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm))
+
+#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm)
+#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm)
+
+#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \
+ | (off))
+
+#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm)
+#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm)
+
+#endif /* PFILTER_OPCODES_ARM_H */
--
1.7.7.3
^ permalink raw reply related
* Re: [PATCH 01/11] SYSCTL: export root and set handling routines
From: Stanislav Kinsbursky @ 2011-12-19 8:56 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org,
linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Pavel Emelianov, neilb-l3A5Bk7waGM@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
James Bottomley, bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
devel-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org
In-Reply-To: <m1bor6rg39.fsf-+imSwln9KH6u2/kzUuoCbdi2O/JbrIOy@public.gmane.org>
18.12.2011 02:25, Eric W. Biederman пишет:
> Stanislav Kinsbursky<skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org> writes:
>
>> These routines are required for making SUNRPC sysctl's per network namespace
>> context.
>
> Why does sunrpc require it's own sysctl root? You should be able to use
> the generic per network namespace root and call it good.
>
> What makes register_net_sysctl_table and register_net_sysctl_ro_table
> unsuitable for sunrpc. I skimmed through your patches and I haven't
> seen anything obvious.
>
> Eric
>
Hello, Eric. Sorry for the lack of information.
I was considering two ways how to make these sysctl per net ns:
1) Use register_net_sysctl_table and register_net_sysctl_ro_table as you
mentioned. This was easy and cheap, but also means, than all user-space
programs, tuning SUNRPC will be broken (since all sysctl currently located
in"/proc/sys/sunprc/").
2) Export sysctl root creation routines and make per-net SUNRPC sysctl root.
This approach allows to make any part of sysctl tree per namespace context and
thus leave user-space stuff unchanged.
BTW, NFS and LockD also have it's sysctls ("/proc/sys/fs/nfs/").
And also because of them I've decided, that it would be better to export SYSCTL
root creation routines instead of breaking compatibility for all NFS layers by
moving all sysctl under /proc/sys/net/ directory.
Do you feel that it was a bad decision?
>
>> Signed-off-by: Stanislav Kinsbursky<skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
>>
>> ---
>> include/linux/sysctl.h | 1 +
>> kernel/sysctl.c | 11 +++++++++++
>> 2 files changed, 12 insertions(+), 0 deletions(-)
>>
>> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
>> index 703cfa3..be586a9 100644
>> --- a/include/linux/sysctl.h
>> +++ b/include/linux/sysctl.h
>> @@ -1084,6 +1084,7 @@ struct ctl_path {
>> };
>>
>> void register_sysctl_root(struct ctl_table_root *root);
>> +void unregister_sysctl_root(struct ctl_table_root *root);
>> struct ctl_table_header *__register_sysctl_paths(
>> struct ctl_table_root *root, struct nsproxy *namespaces,
>> const struct ctl_path *path, struct ctl_table *table);
>> diff --git a/kernel/sysctl.c b/kernel/sysctl.c
>> index ae27196..fb016a9 100644
>> --- a/kernel/sysctl.c
>> +++ b/kernel/sysctl.c
>> @@ -1700,6 +1700,15 @@ void register_sysctl_root(struct ctl_table_root *root)
>> list_add_tail(&root->root_list,&sysctl_table_root.root_list);
>> spin_unlock(&sysctl_lock);
>> }
>> +EXPORT_SYMBOL_GPL(register_sysctl_root);
>> +
>> +void unregister_sysctl_root(struct ctl_table_root *root)
>> +{
>> + spin_lock(&sysctl_lock);
>> + list_del(&root->root_list);
>> + spin_unlock(&sysctl_lock);
>> +}
>> +EXPORT_SYMBOL_GPL(unregister_sysctl_root);
>>
>> /*
>> * sysctl_perm does NOT grant the superuser all rights automatically, because
>> @@ -1925,6 +1934,7 @@ struct ctl_table_header *__register_sysctl_paths(
>>
>> return header;
>> }
>> +EXPORT_SYMBOL_GPL(__register_sysctl_paths);
>>
>> /**
>> * register_sysctl_table_path - register a sysctl table hierarchy
>> @@ -2007,6 +2017,7 @@ void setup_sysctl_set(struct ctl_table_set *p,
>> p->parent = parent ? parent :&sysctl_table_root.default_set;
>> p->is_seen = is_seen;
>> }
>> +EXPORT_SYMBOL_GPL(setup_sysctl_set);
>>
>> #else /* !CONFIG_SYSCTL */
>> struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Best regards,
Stanislav Kinsbursky
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: WARNING: at mm/slub.c:3357, kernel BUG at mm/slub.c:3413
From: Eric W. Biederman @ 2011-12-19 9:06 UTC (permalink / raw)
To: Markus Trippelsdorf
Cc: Eric Dumazet, Alex,Shi, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Christoph Lameter, Pekka Enberg, Matt Mackall,
netdev@vger.kernel.org, tj
In-Reply-To: <20111219091909.GA1614@x4>
Markus Trippelsdorf <markus@trippelsdorf.de> writes:
> On 2011.12.18 at 19:21 -0800, Eric W. Biederman wrote:
>> Markus Trippelsdorf <markus@trippelsdorf.de> writes:
>>
>> > On 2011.11.21 at 17:34 +0100, Markus Trippelsdorf wrote:
>> >> On 2011.11.21 at 17:10 +0100, Markus Trippelsdorf wrote:
>> >> > On 2011.11.21 at 16:48 +0100, Eric Dumazet wrote:
>> >> > > Le lundi 21 novembre 2011 à 16:36 +0100, Markus Trippelsdorf a écrit :
>> >> > > > On 2011.11.21 at 15:16 +0100, Eric Dumazet wrote:
>> >> > > > > Le lundi 21 novembre 2011 à 14:15 +0100, Markus Trippelsdorf a écrit :
>> >> > > > >
>> >> > > > > > I've enabled CONFIG_SLUB_DEBUG_ON and this is what happend:
>> >> > > > > >
>> >> > > > >
>> >> > > > > Thanks
>> >> > > > >
>> >> > > > > Please continue to provide more samples.
>> >> > > > >
>> >> > > > > There is something wrong somewhere, but where exactly, its hard to say.
>> >> > > >
>> >> > > > New sample. This one points to lib/idr.c:
>> >> > > >
>> >> > > > =============================================================================
>> >> > > > BUG idr_layer_cache: Poison overwritten
>> >> > > > -----------------------------------------------------------------------------
>> >> > >
>> >> > > Thanks, could you now add "CONFIG_DEBUG_PAGEALLOC=y" in your config as
>> >> > > well ?
>> >> >
>> >> > Sure. This one happend with CONFIG_DEBUG_PAGEALLOC=y:
>> >> >
>> >> > =============================================================================
>> >> > BUG task_struct: Poison overwritten
>> >> > -----------------------------------------------------------------------------
>> >>
>> >> And sometimes this one that I've reported earlier already:
>> >>
>> >> (see: http://thread.gmane.org/gmane.linux.kernel/1215023 )
>> >>
>> >> ------------[ cut here ]------------
>> >> WARNING: at fs/sysfs/sysfs.h:195 sysfs_get_inode+0x136/0x140()
>> >> Hardware name: System Product Name
>> >> Pid: 1876, comm: slabinfo Not tainted 3.2.0-rc2-00274-g6fe4c6d #72
>> >> Call Trace:
>> >> [<ffffffff8106cac5>] warn_slowpath_common+0x75/0xb0
>> >> [<ffffffff8106cbc5>] warn_slowpath_null+0x15/0x20
>> >> [<ffffffff81163236>] sysfs_get_inode+0x136/0x140
>> >> [<ffffffff81164cef>] sysfs_lookup+0x6f/0x110
>> >> [<ffffffff811173f9>] d_alloc_and_lookup+0x39/0x80
>> >> [<ffffffff81118774>] do_lookup+0x294/0x3a0
>> >> [<ffffffff8111798a>] ? inode_permission+0x7a/0xb0
>> >> [<ffffffff8111a3f7>] do_last.isra.46+0x137/0x7f0
>> >> [<ffffffff8111ab76>] path_openat+0xc6/0x370
>> >> [<ffffffff81117606>] ? getname_flags+0x36/0x230
>> >> [<ffffffff810ec852>] ? handle_mm_fault+0x192/0x290
>> >> [<ffffffff8111ae5c>] do_filp_open+0x3c/0x90
>> >> [<ffffffff81127c8c>] ? alloc_fd+0xdc/0x120
>> >> [<ffffffff8110ce77>] do_sys_open+0xe7/0x1c0
>> >> [<ffffffff8110cf6b>] sys_open+0x1b/0x20
>> >> [<ffffffff814ccb7b>] system_call_fastpath+0x16/0x1b
>> >> ---[ end trace b1377eb8b131d37d ]---
>> >
>> > Hm, the "sysfs: use rb-tree" thing hit again during boot. Could this be
>> > the root cause of this all?
>> >
>> > I wrote down the following:
>> >
>> > RIP : rb_next
>> >
>> > Trace:
>> > sysfs_dir_pos
>> > sysfs_readdir
>> > ? sys_ioctl
>> > vfs_readdir
>> > sys_getdents
>>
>> Thanks for reporting this.
>>
>> Has this by any chance been resolved or stopped happening?
>
> Yes.
>
>> This looks for all of the world like something is stomping your sysfs
>> dirents. I haven't seen anyone else complaining so this seems like the
>> problem is unique to your configuration. Which suggests that it is not
>> sysfs itself that is wrong.
>>
>> I have been through the code a time or two and I haven't seen anything
>> obviously wrong. Everything that sysfs does is protected by the
>> sysfs_mutex so the locking is very very simple.
>>
>> My best guess of why now is that the rbtree code make a sysfs dirent
>> 48 bytes larger. And so it is much more exposed to these kinds of
>> problems.
>
> Sorry, but your subsystem was just accidentally hit by a bug in the
> Radeon driver, that sometimes randomly writes 0 dwords somewhere to
> memory after a kexec boot (see the rest of this huge thread).
> It's still not fixed in mainline, because Linus refused to take the fix
> this late in the series.
Awesome.
I guess that means I am only responsible for the Radeon driver having
the opportunity to take that code path. It is nice to see kexec being
used and being well known enough I didn't have to get involved.
Eric
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: WARNING: at mm/slub.c:3357, kernel BUG at mm/slub.c:3413
From: Markus Trippelsdorf @ 2011-12-19 9:19 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Eric Dumazet, Alex,Shi, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Christoph Lameter, Pekka Enberg, Matt Mackall,
netdev@vger.kernel.org, tj
In-Reply-To: <m1liq9l009.fsf@fess.ebiederm.org>
On 2011.12.18 at 19:21 -0800, Eric W. Biederman wrote:
> Markus Trippelsdorf <markus@trippelsdorf.de> writes:
>
> > On 2011.11.21 at 17:34 +0100, Markus Trippelsdorf wrote:
> >> On 2011.11.21 at 17:10 +0100, Markus Trippelsdorf wrote:
> >> > On 2011.11.21 at 16:48 +0100, Eric Dumazet wrote:
> >> > > Le lundi 21 novembre 2011 à 16:36 +0100, Markus Trippelsdorf a écrit :
> >> > > > On 2011.11.21 at 15:16 +0100, Eric Dumazet wrote:
> >> > > > > Le lundi 21 novembre 2011 à 14:15 +0100, Markus Trippelsdorf a écrit :
> >> > > > >
> >> > > > > > I've enabled CONFIG_SLUB_DEBUG_ON and this is what happend:
> >> > > > > >
> >> > > > >
> >> > > > > Thanks
> >> > > > >
> >> > > > > Please continue to provide more samples.
> >> > > > >
> >> > > > > There is something wrong somewhere, but where exactly, its hard to say.
> >> > > >
> >> > > > New sample. This one points to lib/idr.c:
> >> > > >
> >> > > > =============================================================================
> >> > > > BUG idr_layer_cache: Poison overwritten
> >> > > > -----------------------------------------------------------------------------
> >> > >
> >> > > Thanks, could you now add "CONFIG_DEBUG_PAGEALLOC=y" in your config as
> >> > > well ?
> >> >
> >> > Sure. This one happend with CONFIG_DEBUG_PAGEALLOC=y:
> >> >
> >> > =============================================================================
> >> > BUG task_struct: Poison overwritten
> >> > -----------------------------------------------------------------------------
> >>
> >> And sometimes this one that I've reported earlier already:
> >>
> >> (see: http://thread.gmane.org/gmane.linux.kernel/1215023 )
> >>
> >> ------------[ cut here ]------------
> >> WARNING: at fs/sysfs/sysfs.h:195 sysfs_get_inode+0x136/0x140()
> >> Hardware name: System Product Name
> >> Pid: 1876, comm: slabinfo Not tainted 3.2.0-rc2-00274-g6fe4c6d #72
> >> Call Trace:
> >> [<ffffffff8106cac5>] warn_slowpath_common+0x75/0xb0
> >> [<ffffffff8106cbc5>] warn_slowpath_null+0x15/0x20
> >> [<ffffffff81163236>] sysfs_get_inode+0x136/0x140
> >> [<ffffffff81164cef>] sysfs_lookup+0x6f/0x110
> >> [<ffffffff811173f9>] d_alloc_and_lookup+0x39/0x80
> >> [<ffffffff81118774>] do_lookup+0x294/0x3a0
> >> [<ffffffff8111798a>] ? inode_permission+0x7a/0xb0
> >> [<ffffffff8111a3f7>] do_last.isra.46+0x137/0x7f0
> >> [<ffffffff8111ab76>] path_openat+0xc6/0x370
> >> [<ffffffff81117606>] ? getname_flags+0x36/0x230
> >> [<ffffffff810ec852>] ? handle_mm_fault+0x192/0x290
> >> [<ffffffff8111ae5c>] do_filp_open+0x3c/0x90
> >> [<ffffffff81127c8c>] ? alloc_fd+0xdc/0x120
> >> [<ffffffff8110ce77>] do_sys_open+0xe7/0x1c0
> >> [<ffffffff8110cf6b>] sys_open+0x1b/0x20
> >> [<ffffffff814ccb7b>] system_call_fastpath+0x16/0x1b
> >> ---[ end trace b1377eb8b131d37d ]---
> >
> > Hm, the "sysfs: use rb-tree" thing hit again during boot. Could this be
> > the root cause of this all?
> >
> > I wrote down the following:
> >
> > RIP : rb_next
> >
> > Trace:
> > sysfs_dir_pos
> > sysfs_readdir
> > ? sys_ioctl
> > vfs_readdir
> > sys_getdents
>
> Thanks for reporting this.
>
> Has this by any chance been resolved or stopped happening?
Yes.
> This looks for all of the world like something is stomping your sysfs
> dirents. I haven't seen anyone else complaining so this seems like the
> problem is unique to your configuration. Which suggests that it is not
> sysfs itself that is wrong.
>
> I have been through the code a time or two and I haven't seen anything
> obviously wrong. Everything that sysfs does is protected by the
> sysfs_mutex so the locking is very very simple.
>
> My best guess of why now is that the rbtree code make a sysfs dirent
> 48 bytes larger. And so it is much more exposed to these kinds of
> problems.
Sorry, but your subsystem was just accidentally hit by a bug in the
Radeon driver, that sometimes randomly writes 0 dwords somewhere to
memory after a kexec boot (see the rest of this huge thread).
It's still not fixed in mainline, because Linus refused to take the fix
this late in the series.
--
Markus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH net-next] r8169: Support for byte queue limits
From: igorm @ 2011-12-19 9:27 UTC (permalink / raw)
To: netdev; +Cc: davem, nic_swsd, romieu, therbert, eric.dumazet, Igor Maravic
From: Igor Maravic <igorm@etf.rs>
Changes to r8169 to use byte queue limits.
Signed-off-by: Igor Maravic <igorm@etf.rs>
---
drivers/net/ethernet/realtek/r8169.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 36b2a4b..bfdb5fd 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5326,6 +5326,7 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
{
rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
tp->cur_tx = tp->dirty_tx = 0;
+ netdev_reset_queue(tp->dev);
}
static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
@@ -5460,6 +5461,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
txd->opts1 |= cpu_to_le32(LastFrag);
}
+ netdev_sent_queue(tp->dev, skb->len);
+
return cur_frag;
err_out:
@@ -5624,6 +5627,8 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
void __iomem *ioaddr)
{
unsigned int dirty_tx, tx_left;
+ unsigned int bytes_compl = 0;
+ int tx_compl = 0;
dirty_tx = tp->dirty_tx;
smp_rmb();
@@ -5642,14 +5647,18 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry);
if (status & LastFrag) {
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += tx_skb->skb->len;
+ tx_compl++;
+ bytes_compl += tx_skb->skb->len;
dev_kfree_skb(tx_skb->skb);
tx_skb->skb = NULL;
}
dirty_tx++;
tx_left--;
}
+ dev->stats.tx_packets += tx_compl;
+ dev->stats.tx_bytes += bytes_compl;
+
+ netdev_completed_queue(dev, tx_compl, bytes_compl);
if (tp->dirty_tx != dirty_tx) {
tp->dirty_tx = dirty_tx;
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH net-next] r8169: Support for byte queue limits
From: Igor Maravić @ 2011-12-19 9:29 UTC (permalink / raw)
To: netdev; +Cc: davem, nic_swsd, romieu, therbert, eric.dumazet, Igor Maravic
In-Reply-To: <1324286878-3950-1-git-send-email-igorm@etf.rs>
Resubmitted the patch. Sorry for double signoffs.
BR
Igor
^ permalink raw reply
* Re: [PATCH net-next] r8169: Support for byte queue limits
From: Eric Dumazet @ 2011-12-19 9:46 UTC (permalink / raw)
To: igorm; +Cc: netdev, davem, nic_swsd, romieu, therbert
In-Reply-To: <1324286878-3950-1-git-send-email-igorm@etf.rs>
Le lundi 19 décembre 2011 à 10:27 +0100, igorm@etf.rs a écrit :
> From: Igor Maravic <igorm@etf.rs>
>
> Changes to r8169 to use byte queue limits.
>
> Signed-off-by: Igor Maravic <igorm@etf.rs>
> ---
> drivers/net/ethernet/realtek/r8169.c | 13 +++++++++++--
> 1 files changed, 11 insertions(+), 2 deletions(-)
>
What are the changes in this version, versus prior submissions ?
>
> static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
> @@ -5460,6 +5461,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
> txd->opts1 |= cpu_to_le32(LastFrag);
> }
>
> + netdev_sent_queue(tp->dev, skb->len);
> +
> return cur_frag;
>
Ignoring a review/comment/suggestion is not very wise, since I wont Ack
this patch as is, and I'll remember for your next patches that you dont
care of me taking the time to review your work.
Your choice.
Please call this from rtl8169_start_xmit() instead.
netdev_sent_queue(dev, skb->len);
^ permalink raw reply
* Re: [PATCH net-next] r8169: Support for byte queue limits
From: Igor Maravić @ 2011-12-19 9:53 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, davem, nic_swsd, romieu, therbert
In-Reply-To: <1324287964.3323.107.camel@edumazet-laptop>
>
> What are the changes in this version, versus prior submissions ?
>
You didn't answer to my comments, so I thought that my version was OK.
I'l change this in a sec.
^ 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