* [PATCH net-2.6] jme: Fix unmap error (Causing system freeze)
From: cooldavid @ 2011-07-21 2:57 UTC (permalink / raw)
To: David Miller
Cc: Jason Lamb, linux-netdev, Guo-Fu Tseng, Jason Long, Marcus Becker,
Aries Lee, Devinchiu, Marc Schiffbauer, stable
From: Guo-Fu Tseng <cooldavid@cooldavid.org>
This patch add the missing dma_unmap().
Which solved the critical issue of system freeze on heavy load.
Michal Miroslaw's rejected patch:
[PATCH v2 10/46] net: jme: convert to generic DMA API
Pointed out the issue also, thank you Michal.
But the fix was incorrect. It would unmap needed address
when low memory.
Got lots of feedback from End user and Gentoo Bugzilla.
https://bugs.gentoo.org/show_bug.cgi?id=373109
Thank you all. :)
Cc: stable@kernel.org
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
---
drivers/net/jme.c | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index b5b174a..1973814 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -753,20 +753,28 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i)
struct jme_ring *rxring = &(jme->rxring[0]);
struct jme_buffer_info *rxbi = rxring->bufinf + i;
struct sk_buff *skb;
+ dma_addr_t mapping;
skb = netdev_alloc_skb(jme->dev,
jme->dev->mtu + RX_EXTRA_LEN);
if (unlikely(!skb))
return -ENOMEM;
+ mapping = pci_map_page(jme->pdev, virt_to_page(skb->data),
+ offset_in_page(skb->data), skb_tailroom(skb),
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) {
+ dev_kfree_skb(skb);
+ return -ENOMEM;
+ }
+
+ if (likely(rxbi->mapping))
+ pci_unmap_page(jme->pdev, rxbi->mapping,
+ rxbi->len, PCI_DMA_FROMDEVICE);
+
rxbi->skb = skb;
rxbi->len = skb_tailroom(skb);
- rxbi->mapping = pci_map_page(jme->pdev,
- virt_to_page(skb->data),
- offset_in_page(skb->data),
- rxbi->len,
- PCI_DMA_FROMDEVICE);
-
+ rxbi->mapping = mapping;
return 0;
}
--
1.7.3.4
_______________________________________________
stable mailing list
stable@linux.kernel.org
http://linux.kernel.org/mailman/listinfo/stable
^ permalink raw reply related
* [PATCH net-next] vmxnet3: set netdev parant device before calling netdev_info
From: Shreyas Bhatewara @ 2011-07-21 2:01 UTC (permalink / raw)
To: netdev; +Cc: pv-drivers
Parent device for netdev should be set before netdev_info() can be called
otherwise there is a NULL pointer dereference and probe() fails.
Signed-off-by: Shreyas N Bhatewara <sbhatewara@vmware.com>
--
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 009277e..1a8cc5b 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2993,6 +2993,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
goto err_ver;
}
+ SET_NETDEV_DEV(netdev, &pdev->dev);
vmxnet3_declare_features(adapter, dma64);
adapter->dev_number = atomic_read(&devices_found);
@@ -3038,7 +3039,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues);
- SET_NETDEV_DEV(netdev, &pdev->dev);
err = register_netdev(netdev);
if (err) {
^ permalink raw reply related
* [PATCH v3] net: filter: BPF 'JIT' compiler for PPC64
From: Matt Evans @ 2011-07-21 1:51 UTC (permalink / raw)
To: linuxppc-dev, netdev
In-Reply-To: <4E24E867.9050909@ozlabs.org>
An implementation of a code generator for BPF programs to speed up packet
filtering on PPC64, inspired by Eric Dumazet's x86-64 version.
Filter code is generated as an ABI-compliant function in module_alloc()'d mem
with stackframe & prologue/epilogue generated if required (simple filters don't
need anything more than an li/blr). The filter's local variables, M[], live in
registers. Supports all BPF opcodes, although "complicated" loads from negative
packet offsets (e.g. SKF_LL_OFF) are not yet supported.
There are a couple of further optimisations left for future work; many-pass
assembly with branch-reach reduction and a register allocator to push M[]
variables into volatile registers would improve the code quality further.
This currently supports big-endian 64-bit PowerPC only (but is fairly simple
to port to PPC32 or LE!).
Enabled in the same way as x86-64:
echo 1 > /proc/sys/net/core/bpf_jit_enable
Or, enabled with extra debug output:
echo 2 > /proc/sys/net/core/bpf_jit_enable
Signed-off-by: Matt Evans <matt@ozlabs.org>
---
V3: Added BUILD_BUG_ON to assert PACA CPU ID is 16bits, made a comment (in
LD_MSH) a bit clearer, ratelimited "Unknown opcode" error and moved
bpf_jit.S to bpf_jit_64.S (it doesn't make sense to rename bpf_jit_comp.c as
small portions will eventually get split out into _32/_64.c files when we do
32bit support).
arch/powerpc/Kconfig | 1 +
arch/powerpc/Makefile | 3 +-
arch/powerpc/include/asm/ppc-opcode.h | 40 ++
arch/powerpc/net/Makefile | 4 +
arch/powerpc/net/bpf_jit.h | 227 +++++++++++
arch/powerpc/net/bpf_jit_64.S | 138 +++++++
arch/powerpc/net/bpf_jit_comp.c | 694 +++++++++++++++++++++++++++++++++
7 files changed, 1106 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2729c66..39860fc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -134,6 +134,7 @@ config PPC
select GENERIC_IRQ_SHOW_LEVEL
select HAVE_RCU_TABLE_FREE if SMP
select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_BPF_JIT if PPC64
config EARLY_PRINTK
bool
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index b7212b6..b94740f 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -154,7 +154,8 @@ core-y += arch/powerpc/kernel/ \
arch/powerpc/lib/ \
arch/powerpc/sysdev/ \
arch/powerpc/platforms/ \
- arch/powerpc/math-emu/
+ arch/powerpc/math-emu/ \
+ arch/powerpc/net/
core-$(CONFIG_XMON) += arch/powerpc/xmon/
core-$(CONFIG_KVM) += arch/powerpc/kvm/
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index e472659..e980faa 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -71,6 +71,42 @@
#define PPC_INST_ERATSX 0x7c000126
#define PPC_INST_ERATSX_DOT 0x7c000127
+/* Misc instructions for BPF compiler */
+#define PPC_INST_LD 0xe8000000
+#define PPC_INST_LHZ 0xa0000000
+#define PPC_INST_LWZ 0x80000000
+#define PPC_INST_STD 0xf8000000
+#define PPC_INST_STDU 0xf8000001
+#define PPC_INST_MFLR 0x7c0802a6
+#define PPC_INST_MTLR 0x7c0803a6
+#define PPC_INST_CMPWI 0x2c000000
+#define PPC_INST_CMPDI 0x2c200000
+#define PPC_INST_CMPLW 0x7c000040
+#define PPC_INST_CMPLWI 0x28000000
+#define PPC_INST_ADDI 0x38000000
+#define PPC_INST_ADDIS 0x3c000000
+#define PPC_INST_ADD 0x7c000214
+#define PPC_INST_SUB 0x7c000050
+#define PPC_INST_BLR 0x4e800020
+#define PPC_INST_BLRL 0x4e800021
+#define PPC_INST_MULLW 0x7c0001d6
+#define PPC_INST_MULHWU 0x7c000016
+#define PPC_INST_MULLI 0x1c000000
+#define PPC_INST_DIVWU 0x7c0003d6
+#define PPC_INST_RLWINM 0x54000000
+#define PPC_INST_RLDICR 0x78000004
+#define PPC_INST_SLW 0x7c000030
+#define PPC_INST_SRW 0x7c000430
+#define PPC_INST_AND 0x7c000038
+#define PPC_INST_ANDDOT 0x7c000039
+#define PPC_INST_OR 0x7c000378
+#define PPC_INST_ANDI 0x70000000
+#define PPC_INST_ORI 0x60000000
+#define PPC_INST_ORIS 0x64000000
+#define PPC_INST_NEG 0x7c0000d0
+#define PPC_INST_BRANCH 0x48000000
+#define PPC_INST_BRANCH_COND 0x40800000
+
/* macros to insert fields into opcodes */
#define __PPC_RA(a) (((a) & 0x1f) << 16)
#define __PPC_RB(b) (((b) & 0x1f) << 11)
@@ -83,6 +119,10 @@
#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
#define __PPC_WC(w) (((w) & 0x3) << 21)
#define __PPC_WS(w) (((w) & 0x1f) << 11)
+#define __PPC_SH(s) __PPC_WS(s)
+#define __PPC_MB(s) (((s) & 0x1f) << 6)
+#define __PPC_ME(s) (((s) & 0x1f) << 1)
+#define __PPC_BI(s) (((s) & 0x1f) << 16)
/*
* Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
diff --git a/arch/powerpc/net/Makefile b/arch/powerpc/net/Makefile
new file mode 100644
index 0000000..266b395
--- /dev/null
+++ b/arch/powerpc/net/Makefile
@@ -0,0 +1,4 @@
+#
+# Arch-specific network modules
+#
+obj-$(CONFIG_BPF_JIT) += bpf_jit_64.o bpf_jit_comp.o
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
new file mode 100644
index 0000000..af1ab5e
--- /dev/null
+++ b/arch/powerpc/net/bpf_jit.h
@@ -0,0 +1,227 @@
+/* bpf_jit.h: BPF JIT compiler for PPC64
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
+ *
+ * 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 _BPF_JIT_H
+#define _BPF_JIT_H
+
+#define BPF_PPC_STACK_LOCALS 32
+#define BPF_PPC_STACK_BASIC (48+64)
+#define BPF_PPC_STACK_SAVE (18*8)
+#define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
+ BPF_PPC_STACK_SAVE)
+#define BPF_PPC_SLOWPATH_FRAME (48+64)
+
+/*
+ * Generated code register usage:
+ *
+ * As normal PPC C ABI (e.g. r1=sp, r2=TOC), with:
+ *
+ * skb r3 (Entry parameter)
+ * A register r4
+ * X register r5
+ * addr param r6
+ * r7-r10 scratch
+ * skb->data r14
+ * skb headlen r15 (skb->len - skb->data_len)
+ * m[0] r16
+ * m[...] ...
+ * m[15] r31
+ */
+#define r_skb 3
+#define r_ret 3
+#define r_A 4
+#define r_X 5
+#define r_addr 6
+#define r_scratch1 7
+#define r_D 14
+#define r_HL 15
+#define r_M 16
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Assembly helpers from arch/powerpc/net/bpf_jit.S:
+ */
+extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
+
+#define FUNCTION_DESCR_SIZE 24
+
+/*
+ * 16-bit immediate helper macros: HA() is for use with sign-extending instrs
+ * (e.g. LD, ADDI). If the bottom 16 bits is "-ve", add another bit into the
+ * top half to negate the effect (i.e. 0xffff + 1 = 0x(1)0000).
+ */
+#define IMM_H(i) ((uintptr_t)(i)>>16)
+#define IMM_HA(i) (((uintptr_t)(i)>>16) + \
+ (((uintptr_t)(i) & 0x8000) >> 15))
+#define IMM_L(i) ((uintptr_t)(i) & 0xffff)
+
+#define PLANT_INSTR(d, idx, instr) \
+ do { if (d) { (d)[idx] = instr; } idx++; } while (0)
+#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
+
+#define PPC_NOP() EMIT(PPC_INST_NOP)
+#define PPC_BLR() EMIT(PPC_INST_BLR)
+#define PPC_BLRL() EMIT(PPC_INST_BLRL)
+#define PPC_MTLR(r) EMIT(PPC_INST_MTLR | __PPC_RT(r))
+#define PPC_ADDI(d, a, i) EMIT(PPC_INST_ADDI | __PPC_RT(d) | \
+ __PPC_RA(a) | IMM_L(i))
+#define PPC_MR(d, a) PPC_OR(d, a, a)
+#define PPC_LI(r, i) PPC_ADDI(r, 0, i)
+#define PPC_ADDIS(d, a, i) EMIT(PPC_INST_ADDIS | \
+ __PPC_RS(d) | __PPC_RA(a) | IMM_L(i))
+#define PPC_LIS(r, i) PPC_ADDIS(r, 0, i)
+#define PPC_STD(r, base, i) EMIT(PPC_INST_STD | __PPC_RS(r) | \
+ __PPC_RA(base) | ((i) & 0xfffc))
+
+#define PPC_LD(r, base, i) EMIT(PPC_INST_LD | __PPC_RT(r) | \
+ __PPC_RA(base) | IMM_L(i))
+#define PPC_LWZ(r, base, i) EMIT(PPC_INST_LWZ | __PPC_RT(r) | \
+ __PPC_RA(base) | IMM_L(i))
+#define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | __PPC_RT(r) | \
+ __PPC_RA(base) | IMM_L(i))
+/* Convenience helpers for the above with 'far' offsets: */
+#define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \
+ else { PPC_ADDIS(r, base, IMM_HA(i)); \
+ PPC_LD(r, r, IMM_L(i)); } } while(0)
+
+#define PPC_LWZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LWZ(r, base, i); \
+ else { PPC_ADDIS(r, base, IMM_HA(i)); \
+ PPC_LWZ(r, r, IMM_L(i)); } } while(0)
+
+#define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LHZ(r, base, i); \
+ else { PPC_ADDIS(r, base, IMM_HA(i)); \
+ PPC_LHZ(r, r, IMM_L(i)); } } while(0)
+
+#define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | __PPC_RA(a) | IMM_L(i))
+#define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | __PPC_RA(a) | IMM_L(i))
+#define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | __PPC_RA(a) | IMM_L(i))
+#define PPC_CMPLW(a, b) EMIT(PPC_INST_CMPLW | __PPC_RA(a) | __PPC_RB(b))
+
+#define PPC_SUB(d, a, b) EMIT(PPC_INST_SUB | __PPC_RT(d) | \
+ __PPC_RB(a) | __PPC_RA(b))
+#define PPC_ADD(d, a, b) EMIT(PPC_INST_ADD | __PPC_RT(d) | \
+ __PPC_RA(a) | __PPC_RB(b))
+#define PPC_MUL(d, a, b) EMIT(PPC_INST_MULLW | __PPC_RT(d) | \
+ __PPC_RA(a) | __PPC_RB(b))
+#define PPC_MULHWU(d, a, b) EMIT(PPC_INST_MULHWU | __PPC_RT(d) | \
+ __PPC_RA(a) | __PPC_RB(b))
+#define PPC_MULI(d, a, i) EMIT(PPC_INST_MULLI | __PPC_RT(d) | \
+ __PPC_RA(a) | IMM_L(i))
+#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | __PPC_RT(d) | \
+ __PPC_RA(a) | __PPC_RB(b))
+#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_RB(b))
+#define PPC_ANDI(d, a, i) EMIT(PPC_INST_ANDI | __PPC_RA(d) | \
+ __PPC_RS(a) | IMM_L(i))
+#define PPC_AND_DOT(d, a, b) EMIT(PPC_INST_ANDDOT | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_RB(b))
+#define PPC_OR(d, a, b) EMIT(PPC_INST_OR | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_RB(b))
+#define PPC_ORI(d, a, i) EMIT(PPC_INST_ORI | __PPC_RA(d) | \
+ __PPC_RS(a) | IMM_L(i))
+#define PPC_ORIS(d, a, i) EMIT(PPC_INST_ORIS | __PPC_RA(d) | \
+ __PPC_RS(a) | IMM_L(i))
+#define PPC_SLW(d, a, s) EMIT(PPC_INST_SLW | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_RB(s))
+#define PPC_SRW(d, a, s) EMIT(PPC_INST_SRW | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_RB(s))
+/* slwi = rlwinm Rx, Ry, n, 0, 31-n */
+#define PPC_SLWI(d, a, i) EMIT(PPC_INST_RLWINM | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_SH(i) | \
+ __PPC_MB(0) | __PPC_ME(31-(i)))
+/* srwi = rlwinm Rx, Ry, 32-n, n, 31 */
+#define PPC_SRWI(d, a, i) EMIT(PPC_INST_RLWINM | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_SH(32-(i)) | \
+ __PPC_MB(i) | __PPC_ME(31))
+/* sldi = rldicr Rx, Ry, n, 63-n */
+#define PPC_SLDI(d, a, i) EMIT(PPC_INST_RLDICR | __PPC_RA(d) | \
+ __PPC_RS(a) | __PPC_SH(i) | \
+ __PPC_MB(63-(i)) | (((i) & 0x20) >> 4))
+#define PPC_NEG(d, a) EMIT(PPC_INST_NEG | __PPC_RT(d) | __PPC_RA(a))
+
+/* Long jump; (unconditional 'branch') */
+#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
+ (((dest) - (ctx->idx * 4)) & 0x03fffffc))
+/* "cond" here covers BO:BI fields. */
+#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \
+ (((cond) & 0x3ff) << 16) | \
+ (((dest) - (ctx->idx * 4)) & \
+ 0xfffc))
+#define PPC_LI32(d, i) do { PPC_LI(d, IMM_L(i)); \
+ if ((u32)(uintptr_t)(i) >= 32768) { \
+ PPC_ADDIS(d, d, IMM_HA(i)); \
+ } } while(0)
+#define PPC_LI64(d, i) do { \
+ if (!((uintptr_t)(i) & 0xffffffff00000000ULL)) \
+ PPC_LI32(d, i); \
+ else { \
+ PPC_LIS(d, ((uintptr_t)(i) >> 48)); \
+ if ((uintptr_t)(i) & 0x0000ffff00000000ULL) \
+ PPC_ORI(d, d, \
+ ((uintptr_t)(i) >> 32) & 0xffff); \
+ PPC_SLDI(d, d, 32); \
+ if ((uintptr_t)(i) & 0x00000000ffff0000ULL) \
+ PPC_ORIS(d, d, \
+ ((uintptr_t)(i) >> 16) & 0xffff); \
+ if ((uintptr_t)(i) & 0x000000000000ffffULL) \
+ PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \
+ } } while (0);
+
+static inline bool is_nearbranch(int offset)
+{
+ return (offset < 32768) && (offset >= -32768);
+}
+
+/*
+ * The fly in the ointment of code size changing from pass to pass is
+ * avoided by padding the short branch case with a NOP. If code size differs
+ * with different branch reaches we will have the issue of code moving from
+ * one pass to the next and will need a few passes to converge on a stable
+ * state.
+ */
+#define PPC_BCC(cond, dest) do { \
+ if (is_nearbranch((dest) - (ctx->idx * 4))) { \
+ PPC_BCC_SHORT(cond, dest); \
+ PPC_NOP(); \
+ } else { \
+ /* Flip the 'T or F' bit to invert comparison */ \
+ PPC_BCC_SHORT(cond ^ COND_CMP_TRUE, (ctx->idx+2)*4); \
+ PPC_JMP(dest); \
+ } } while(0)
+
+/* To create a branch condition, select a bit of cr0... */
+#define CR0_LT 0
+#define CR0_GT 1
+#define CR0_EQ 2
+/* ...and modify BO[3] */
+#define COND_CMP_TRUE 0x100
+#define COND_CMP_FALSE 0x000
+/* Together, they make all required comparisons: */
+#define COND_GT (CR0_GT | COND_CMP_TRUE)
+#define COND_GE (CR0_LT | COND_CMP_FALSE)
+#define COND_EQ (CR0_EQ | COND_CMP_TRUE)
+#define COND_NE (CR0_EQ | COND_CMP_FALSE)
+#define COND_LT (CR0_LT | COND_CMP_TRUE)
+
+#define SEEN_DATAREF 0x10000 /* might call external helpers */
+#define SEEN_XREG 0x20000 /* X reg is used */
+#define SEEN_MEM 0x40000 /* SEEN_MEM+(1<<n) = use mem[n] for temporary
+ * storage */
+#define SEEN_MEM_MSK 0x0ffff
+
+struct codegen_context {
+ unsigned int seen;
+ unsigned int idx;
+ int pc_ret0; /* bpf index of first RET #0 instruction (if any) */
+};
+
+#endif
+
+#endif
diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S
new file mode 100644
index 0000000..ff4506e
--- /dev/null
+++ b/arch/powerpc/net/bpf_jit_64.S
@@ -0,0 +1,138 @@
+/* bpf_jit.S: Packet/header access helper functions
+ * for PPC64 BPF compiler.
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
+ *
+ * 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 <asm/ppc_asm.h>
+#include "bpf_jit.h"
+
+/*
+ * All of these routines are called directly from generated code,
+ * whose register usage is:
+ *
+ * r3 skb
+ * r4,r5 A,X
+ * r6 *** address parameter to helper ***
+ * r7-r10 scratch
+ * r14 skb->data
+ * r15 skb headlen
+ * r16-31 M[]
+ */
+
+/*
+ * To consider: These helpers are so small it could be better to just
+ * generate them inline. Inline code can do the simple headlen check
+ * then branch directly to slow_path_XXX if required. (In fact, could
+ * load a spare GPR with the address of slow_path_generic and pass size
+ * as an argument, making the call site a mtlr, li and bllr.)
+ *
+ * Technically, the "is addr < 0" check is unnecessary & slowing down
+ * the ABS path, as it's statically checked on generation.
+ */
+ .globl sk_load_word
+sk_load_word:
+ cmpdi r_addr, 0
+ blt bpf_error
+ /* Are we accessing past headlen? */
+ subi r_scratch1, r_HL, 4
+ cmpd r_scratch1, r_addr
+ blt bpf_slow_path_word
+ /* Nope, just hitting the header. cr0 here is eq or gt! */
+ lwzx r_A, r_D, r_addr
+ /* When big endian we don't need to byteswap. */
+ blr /* Return success, cr0 != LT */
+
+ .globl sk_load_half
+sk_load_half:
+ cmpdi r_addr, 0
+ blt bpf_error
+ subi r_scratch1, r_HL, 2
+ cmpd r_scratch1, r_addr
+ blt bpf_slow_path_half
+ lhzx r_A, r_D, r_addr
+ blr
+
+ .globl sk_load_byte
+sk_load_byte:
+ cmpdi r_addr, 0
+ blt bpf_error
+ cmpd r_HL, r_addr
+ ble bpf_slow_path_byte
+ lbzx r_A, r_D, r_addr
+ blr
+
+/*
+ * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf)
+ * r_addr is the offset value, already known positive
+ */
+ .globl sk_load_byte_msh
+sk_load_byte_msh:
+ cmpd r_HL, r_addr
+ ble bpf_slow_path_byte_msh
+ lbzx r_X, r_D, r_addr
+ rlwinm r_X, r_X, 2, 32-4-2, 31-2
+ blr
+
+bpf_error:
+ /* Entered with cr0 = lt */
+ li r3, 0
+ /* Generated code will 'blt epilogue', returning 0. */
+ blr
+
+/* Call out to skb_copy_bits:
+ * We'll need to back up our volatile regs first; we have
+ * local variable space at r1+(BPF_PPC_STACK_BASIC).
+ * Allocate a new stack frame here to remain ABI-compliant in
+ * stashing LR.
+ */
+#define bpf_slow_path_common(SIZE) \
+ mflr r0; \
+ std r0, 16(r1); \
+ /* R3 goes in parameter space of caller's frame */ \
+ std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
+ std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
+ std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
+ addi r5, r1, BPF_PPC_STACK_BASIC+(2*8); \
+ stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \
+ /* R3 = r_skb, as passed */ \
+ mr r4, r_addr; \
+ li r6, SIZE; \
+ bl skb_copy_bits; \
+ /* R3 = 0 on success */ \
+ addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
+ ld r0, 16(r1); \
+ ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
+ ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
+ mtlr r0; \
+ cmpdi r3, 0; \
+ blt bpf_error; /* cr0 = LT */ \
+ ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
+ /* Great success! */
+
+bpf_slow_path_word:
+ bpf_slow_path_common(4)
+ /* Data value is on stack, and cr0 != LT */
+ lwz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
+ blr
+
+bpf_slow_path_half:
+ bpf_slow_path_common(2)
+ lhz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
+ blr
+
+bpf_slow_path_byte:
+ bpf_slow_path_common(1)
+ lbz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
+ blr
+
+bpf_slow_path_byte_msh:
+ bpf_slow_path_common(1)
+ lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
+ rlwinm r_X, r_X, 2, 32-4-2, 31-2
+ blr
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
new file mode 100644
index 0000000..73619d3
--- /dev/null
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -0,0 +1,694 @@
+/* bpf_jit_comp.c: BPF JIT compiler for PPC64
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
+ *
+ * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@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/moduleloader.h>
+#include <asm/cacheflush.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include "bpf_jit.h"
+
+#ifndef __BIG_ENDIAN
+/* There are endianness assumptions herein. */
+#error "Little-endian PPC not supported in BPF compiler"
+#endif
+
+int bpf_jit_enable __read_mostly;
+
+
+static inline void bpf_flush_icache(void *start, void *end)
+{
+ smp_wmb();
+ flush_icache_range((unsigned long)start, (unsigned long)end);
+}
+
+static void bpf_jit_build_prologue(struct sk_filter *fp, u32 *image,
+ struct codegen_context *ctx)
+{
+ int i;
+ const struct sock_filter *filter = fp->insns;
+
+ if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
+ /* Make stackframe */
+ if (ctx->seen & SEEN_DATAREF) {
+ /* If we call any helpers (for loads), save LR */
+ EMIT(PPC_INST_MFLR | __PPC_RT(0));
+ PPC_STD(0, 1, 16);
+
+ /* Back up non-volatile regs. */
+ PPC_STD(r_D, 1, -(8*(32-r_D)));
+ PPC_STD(r_HL, 1, -(8*(32-r_HL)));
+ }
+ if (ctx->seen & SEEN_MEM) {
+ /*
+ * Conditionally save regs r15-r31 as some will be used
+ * for M[] data.
+ */
+ for (i = r_M; i < (r_M+16); i++) {
+ if (ctx->seen & (1 << (i-r_M)))
+ PPC_STD(i, 1, -(8*(32-i)));
+ }
+ }
+ EMIT(PPC_INST_STDU | __PPC_RS(1) | __PPC_RA(1) |
+ (-BPF_PPC_STACKFRAME & 0xfffc));
+ }
+
+ if (ctx->seen & SEEN_DATAREF) {
+ /*
+ * If this filter needs to access skb data,
+ * prepare r_D and r_HL:
+ * r_HL = skb->len - skb->data_len
+ * r_D = skb->data
+ */
+ PPC_LWZ_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
+ data_len));
+ PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len));
+ PPC_SUB(r_HL, r_HL, r_scratch1);
+ PPC_LD_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
+ }
+
+ if (ctx->seen & SEEN_XREG) {
+ /*
+ * TODO: Could also detect whether first instr. sets X and
+ * avoid this (as below, with A).
+ */
+ PPC_LI(r_X, 0);
+ }
+
+ switch (filter[0].code) {
+ case BPF_S_RET_K:
+ case BPF_S_LD_W_LEN:
+ case BPF_S_ANC_PROTOCOL:
+ case BPF_S_ANC_IFINDEX:
+ case BPF_S_ANC_MARK:
+ case BPF_S_ANC_RXHASH:
+ case BPF_S_ANC_CPU:
+ case BPF_S_ANC_QUEUE:
+ case BPF_S_LD_W_ABS:
+ case BPF_S_LD_H_ABS:
+ case BPF_S_LD_B_ABS:
+ /* first instruction sets A register (or is RET 'constant') */
+ break;
+ default:
+ /* make sure we dont leak kernel information to user */
+ PPC_LI(r_A, 0);
+ }
+}
+
+static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
+{
+ int i;
+
+ if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
+ PPC_ADDI(1, 1, BPF_PPC_STACKFRAME);
+ if (ctx->seen & SEEN_DATAREF) {
+ PPC_LD(0, 1, 16);
+ PPC_MTLR(0);
+ PPC_LD(r_D, 1, -(8*(32-r_D)));
+ PPC_LD(r_HL, 1, -(8*(32-r_HL)));
+ }
+ if (ctx->seen & SEEN_MEM) {
+ /* Restore any saved non-vol registers */
+ for (i = r_M; i < (r_M+16); i++) {
+ if (ctx->seen & (1 << (i-r_M)))
+ PPC_LD(i, 1, -(8*(32-i)));
+ }
+ }
+ }
+ /* The RETs have left a return value in R3. */
+
+ PPC_BLR();
+}
+
+/* Assemble the body code between the prologue & epilogue. */
+static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
+ struct codegen_context *ctx,
+ unsigned int *addrs)
+{
+ const struct sock_filter *filter = fp->insns;
+ int flen = fp->len;
+ u8 *func;
+ unsigned int true_cond;
+ int i;
+
+ /* Start of epilogue code */
+ unsigned int exit_addr = addrs[flen];
+
+ for (i = 0; i < flen; i++) {
+ unsigned int K = filter[i].k;
+
+ /*
+ * addrs[] maps a BPF bytecode address into a real offset from
+ * the start of the body code.
+ */
+ addrs[i] = ctx->idx * 4;
+
+ switch (filter[i].code) {
+ /*** ALU ops ***/
+ case BPF_S_ALU_ADD_X: /* A += X; */
+ ctx->seen |= SEEN_XREG;
+ PPC_ADD(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_ADD_K: /* A += K; */
+ if (!K)
+ break;
+ PPC_ADDI(r_A, r_A, IMM_L(K));
+ if (K >= 32768)
+ PPC_ADDIS(r_A, r_A, IMM_HA(K));
+ break;
+ case BPF_S_ALU_SUB_X: /* A -= X; */
+ ctx->seen |= SEEN_XREG;
+ PPC_SUB(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_SUB_K: /* A -= K */
+ if (!K)
+ break;
+ PPC_ADDI(r_A, r_A, IMM_L(-K));
+ if (K >= 32768)
+ PPC_ADDIS(r_A, r_A, IMM_HA(-K));
+ break;
+ case BPF_S_ALU_MUL_X: /* A *= X; */
+ ctx->seen |= SEEN_XREG;
+ PPC_MUL(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_MUL_K: /* A *= K */
+ if (K < 32768)
+ PPC_MULI(r_A, r_A, K);
+ else {
+ PPC_LI32(r_scratch1, K);
+ PPC_MUL(r_A, r_A, r_scratch1);
+ }
+ break;
+ case BPF_S_ALU_DIV_X: /* A /= X; */
+ ctx->seen |= SEEN_XREG;
+ PPC_CMPWI(r_X, 0);
+ if (ctx->pc_ret0 != -1) {
+ PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
+ } else {
+ /*
+ * Exit, returning 0; first pass hits here
+ * (longer worst-case code size).
+ */
+ PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
+ PPC_LI(r_ret, 0);
+ PPC_JMP(exit_addr);
+ }
+ PPC_DIVWU(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
+ PPC_LI32(r_scratch1, K);
+ /* Top 32 bits of 64bit result -> A */
+ PPC_MULHWU(r_A, r_A, r_scratch1);
+ break;
+ case BPF_S_ALU_AND_X:
+ ctx->seen |= SEEN_XREG;
+ PPC_AND(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_AND_K:
+ if (!IMM_H(K))
+ PPC_ANDI(r_A, r_A, K);
+ else {
+ PPC_LI32(r_scratch1, K);
+ PPC_AND(r_A, r_A, r_scratch1);
+ }
+ break;
+ case BPF_S_ALU_OR_X:
+ ctx->seen |= SEEN_XREG;
+ PPC_OR(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_OR_K:
+ if (IMM_L(K))
+ PPC_ORI(r_A, r_A, IMM_L(K));
+ if (K >= 65536)
+ PPC_ORIS(r_A, r_A, IMM_H(K));
+ break;
+ case BPF_S_ALU_LSH_X: /* A <<= X; */
+ ctx->seen |= SEEN_XREG;
+ PPC_SLW(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_LSH_K:
+ if (K == 0)
+ break;
+ else
+ PPC_SLWI(r_A, r_A, K);
+ break;
+ case BPF_S_ALU_RSH_X: /* A >>= X; */
+ ctx->seen |= SEEN_XREG;
+ PPC_SRW(r_A, r_A, r_X);
+ break;
+ case BPF_S_ALU_RSH_K: /* A >>= K; */
+ if (K == 0)
+ break;
+ else
+ PPC_SRWI(r_A, r_A, K);
+ break;
+ case BPF_S_ALU_NEG:
+ PPC_NEG(r_A, r_A);
+ break;
+ case BPF_S_RET_K:
+ PPC_LI32(r_ret, K);
+ if (!K) {
+ if (ctx->pc_ret0 == -1)
+ ctx->pc_ret0 = i;
+ }
+ /*
+ * If this isn't the very last instruction, branch to
+ * the epilogue if we've stuff to clean up. Otherwise,
+ * if there's nothing to tidy, just return. If we /are/
+ * the last instruction, we're about to fall through to
+ * the epilogue to return.
+ */
+ if (i != flen - 1) {
+ /*
+ * Note: 'seen' is properly valid only on pass
+ * #2. Both parts of this conditional are the
+ * same instruction size though, meaning the
+ * first pass will still correctly determine the
+ * code size/addresses.
+ */
+ if (ctx->seen)
+ PPC_JMP(exit_addr);
+ else
+ PPC_BLR();
+ }
+ break;
+ case BPF_S_RET_A:
+ PPC_MR(r_ret, r_A);
+ if (i != flen - 1) {
+ if (ctx->seen)
+ PPC_JMP(exit_addr);
+ else
+ PPC_BLR();
+ }
+ break;
+ case BPF_S_MISC_TAX: /* X = A */
+ PPC_MR(r_X, r_A);
+ break;
+ case BPF_S_MISC_TXA: /* A = X */
+ ctx->seen |= SEEN_XREG;
+ PPC_MR(r_A, r_X);
+ break;
+
+ /*** Constant loads/M[] access ***/
+ case BPF_S_LD_IMM: /* A = K */
+ PPC_LI32(r_A, K);
+ break;
+ case BPF_S_LDX_IMM: /* X = K */
+ PPC_LI32(r_X, K);
+ break;
+ case BPF_S_LD_MEM: /* A = mem[K] */
+ PPC_MR(r_A, r_M + (K & 0xf));
+ ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
+ break;
+ case BPF_S_LDX_MEM: /* X = mem[K] */
+ PPC_MR(r_X, r_M + (K & 0xf));
+ ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
+ break;
+ case BPF_S_ST: /* mem[K] = A */
+ PPC_MR(r_M + (K & 0xf), r_A);
+ ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
+ break;
+ case BPF_S_STX: /* mem[K] = X */
+ PPC_MR(r_M + (K & 0xf), r_X);
+ ctx->seen |= SEEN_XREG | SEEN_MEM | (1<<(K & 0xf));
+ break;
+ case BPF_S_LD_W_LEN: /* A = skb->len; */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+ PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len));
+ break;
+ case BPF_S_LDX_W_LEN: /* X = skb->len; */
+ PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, len));
+ break;
+
+ /*** Ancillary info loads ***/
+
+ /* None of the BPF_S_ANC* codes appear to be passed by
+ * sk_chk_filter(). The interpreter and the x86 BPF
+ * compiler implement them so we do too -- they may be
+ * planted in future.
+ */
+ case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ protocol) != 2);
+ PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
+ protocol));
+ /* ntohs is a NOP with BE loads. */
+ break;
+ case BPF_S_ANC_IFINDEX:
+ PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
+ dev));
+ PPC_CMPDI(r_scratch1, 0);
+ if (ctx->pc_ret0 != -1) {
+ PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
+ } else {
+ /* Exit, returning 0; first pass hits here. */
+ PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
+ PPC_LI(r_ret, 0);
+ PPC_JMP(exit_addr);
+ }
+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
+ ifindex) != 4);
+ PPC_LWZ_OFFS(r_A, r_scratch1,
+ offsetof(struct net_device, ifindex));
+ break;
+ case BPF_S_ANC_MARK:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+ PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
+ mark));
+ break;
+ case BPF_S_ANC_RXHASH:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
+ PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
+ rxhash));
+ break;
+ case BPF_S_ANC_QUEUE:
+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
+ queue_mapping) != 2);
+ PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
+ queue_mapping));
+ break;
+ case BPF_S_ANC_CPU:
+#ifdef CONFIG_SMP
+ /*
+ * PACA ptr is r13:
+ * raw_smp_processor_id() = local_paca->paca_index
+ */
+ BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct,
+ paca_index) != 2);
+ PPC_LHZ_OFFS(r_A, 13,
+ offsetof(struct paca_struct, paca_index));
+#else
+ PPC_LI(r_A, 0);
+#endif
+ break;
+
+ /*** Absolute loads from packet header/data ***/
+ case BPF_S_LD_W_ABS:
+ func = sk_load_word;
+ goto common_load;
+ case BPF_S_LD_H_ABS:
+ func = sk_load_half;
+ goto common_load;
+ case BPF_S_LD_B_ABS:
+ func = sk_load_byte;
+ common_load:
+ /*
+ * Load from [K]. Reference with the (negative)
+ * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
+ */
+ ctx->seen |= SEEN_DATAREF;
+ if ((int)K < 0)
+ return -ENOTSUPP;
+ PPC_LI64(r_scratch1, func);
+ PPC_MTLR(r_scratch1);
+ PPC_LI32(r_addr, K);
+ PPC_BLRL();
+ /*
+ * Helper returns 'lt' condition on error, and an
+ * appropriate return value in r3
+ */
+ PPC_BCC(COND_LT, exit_addr);
+ break;
+
+ /*** Indirect loads from packet header/data ***/
+ case BPF_S_LD_W_IND:
+ func = sk_load_word;
+ goto common_load_ind;
+ case BPF_S_LD_H_IND:
+ func = sk_load_half;
+ goto common_load_ind;
+ case BPF_S_LD_B_IND:
+ func = sk_load_byte;
+ common_load_ind:
+ /*
+ * Load from [X + K]. Negative offsets are tested for
+ * in the helper functions, and result in a 'ret 0'.
+ */
+ ctx->seen |= SEEN_DATAREF | SEEN_XREG;
+ PPC_LI64(r_scratch1, func);
+ PPC_MTLR(r_scratch1);
+ PPC_ADDI(r_addr, r_X, IMM_L(K));
+ if (K >= 32768)
+ PPC_ADDIS(r_addr, r_addr, IMM_HA(K));
+ PPC_BLRL();
+ /* If error, cr0.LT set */
+ PPC_BCC(COND_LT, exit_addr);
+ break;
+
+ case BPF_S_LDX_B_MSH:
+ /*
+ * x86 version drops packet (RET 0) when K<0, whereas
+ * interpreter does allow K<0 (__load_pointer, special
+ * ancillary data). common_load returns ENOTSUPP if K<0,
+ * so we fall back to interpreter & filter works.
+ */
+ func = sk_load_byte_msh;
+ goto common_load;
+ break;
+
+ /*** Jump and branches ***/
+ case BPF_S_JMP_JA:
+ if (K != 0)
+ PPC_JMP(addrs[i + 1 + K]);
+ break;
+
+ case BPF_S_JMP_JGT_K:
+ case BPF_S_JMP_JGT_X:
+ true_cond = COND_GT;
+ goto cond_branch;
+ case BPF_S_JMP_JGE_K:
+ case BPF_S_JMP_JGE_X:
+ true_cond = COND_GE;
+ goto cond_branch;
+ case BPF_S_JMP_JEQ_K:
+ case BPF_S_JMP_JEQ_X:
+ true_cond = COND_EQ;
+ goto cond_branch;
+ case BPF_S_JMP_JSET_K:
+ case BPF_S_JMP_JSET_X:
+ true_cond = COND_NE;
+ /* Fall through */
+ cond_branch:
+ /* same targets, can avoid doing the test :) */
+ if (filter[i].jt == filter[i].jf) {
+ if (filter[i].jt > 0)
+ PPC_JMP(addrs[i + 1 + filter[i].jt]);
+ break;
+ }
+
+ switch (filter[i].code) {
+ case BPF_S_JMP_JGT_X:
+ case BPF_S_JMP_JGE_X:
+ case BPF_S_JMP_JEQ_X:
+ ctx->seen |= SEEN_XREG;
+ PPC_CMPLW(r_A, r_X);
+ break;
+ case BPF_S_JMP_JSET_X:
+ ctx->seen |= SEEN_XREG;
+ PPC_AND_DOT(r_scratch1, r_A, r_X);
+ break;
+ case BPF_S_JMP_JEQ_K:
+ case BPF_S_JMP_JGT_K:
+ case BPF_S_JMP_JGE_K:
+ if (K < 32768)
+ PPC_CMPLWI(r_A, K);
+ else {
+ PPC_LI32(r_scratch1, K);
+ PPC_CMPLW(r_A, r_scratch1);
+ }
+ break;
+ case BPF_S_JMP_JSET_K:
+ if (K < 32768)
+ /* PPC_ANDI is /only/ dot-form */
+ PPC_ANDI(r_scratch1, r_A, K);
+ else {
+ PPC_LI32(r_scratch1, K);
+ PPC_AND_DOT(r_scratch1, r_A,
+ r_scratch1);
+ }
+ break;
+ }
+ /* Sometimes branches are constructed "backward", with
+ * the false path being the branch and true path being
+ * a fallthrough to the next instruction.
+ */
+ if (filter[i].jt == 0)
+ /* Swap the sense of the branch */
+ PPC_BCC(true_cond ^ COND_CMP_TRUE,
+ addrs[i + 1 + filter[i].jf]);
+ else {
+ PPC_BCC(true_cond, addrs[i + 1 + filter[i].jt]);
+ if (filter[i].jf != 0)
+ PPC_JMP(addrs[i + 1 + filter[i].jf]);
+ }
+ break;
+ default:
+ /* The filter contains something cruel & unusual.
+ * We don't handle it, but also there shouldn't be
+ * anything missing from our list.
+ */
+ if (printk_ratelimit())
+ pr_err("BPF filter opcode %04x (@%d) unsupported\n",
+ filter[i].code, i);
+ return -ENOTSUPP;
+ }
+
+ }
+ /* Set end-of-body-code address for exit. */
+ addrs[i] = ctx->idx * 4;
+
+ return 0;
+}
+
+void bpf_jit_compile(struct sk_filter *fp)
+{
+ unsigned int proglen;
+ unsigned int alloclen;
+ u32 *image = NULL;
+ u32 *code_base;
+ unsigned int *addrs;
+ struct codegen_context cgctx;
+ int pass;
+ int flen = fp->len;
+
+ if (!bpf_jit_enable)
+ return;
+
+ addrs = kzalloc((flen+1) * sizeof(*addrs), GFP_KERNEL);
+ if (addrs == NULL)
+ return;
+
+ /*
+ * There are multiple assembly passes as the generated code will change
+ * size as it settles down, figuring out the max branch offsets/exit
+ * paths required.
+ *
+ * The range of standard conditional branches is +/- 32Kbytes. Since
+ * BPF_MAXINSNS = 4096, we can only jump from (worst case) start to
+ * finish with 8 bytes/instruction. Not feasible, so long jumps are
+ * used, distinct from short branches.
+ *
+ * Current:
+ *
+ * For now, both branch types assemble to 2 words (short branches padded
+ * with a NOP); this is less efficient, but assembly will always complete
+ * after exactly 3 passes:
+ *
+ * First pass: No code buffer; Program is "faux-generated" -- no code
+ * emitted but maximum size of output determined (and addrs[] filled
+ * in). Also, we note whether we use M[], whether we use skb data, etc.
+ * All generation choices assumed to be 'worst-case', e.g. branches all
+ * far (2 instructions), return path code reduction not available, etc.
+ *
+ * Second pass: Code buffer allocated with size determined previously.
+ * Prologue generated to support features we have seen used. Exit paths
+ * determined and addrs[] is filled in again, as code may be slightly
+ * smaller as a result.
+ *
+ * Third pass: Code generated 'for real', and branch destinations
+ * determined from now-accurate addrs[] map.
+ *
+ * Ideal:
+ *
+ * If we optimise this, near branches will be shorter. On the
+ * first assembly pass, we should err on the side of caution and
+ * generate the biggest code. On subsequent passes, branches will be
+ * generated short or long and code size will reduce. With smaller
+ * code, more branches may fall into the short category, and code will
+ * reduce more.
+ *
+ * Finally, if we see one pass generate code the same size as the
+ * previous pass we have converged and should now generate code for
+ * real. Allocating at the end will also save the memory that would
+ * otherwise be wasted by the (small) current code shrinkage.
+ * Preferably, we should do a small number of passes (e.g. 5) and if we
+ * haven't converged by then, get impatient and force code to generate
+ * as-is, even if the odd branch would be left long. The chances of a
+ * long jump are tiny with all but the most enormous of BPF filter
+ * inputs, so we should usually converge on the third pass.
+ */
+
+ cgctx.idx = 0;
+ cgctx.seen = 0;
+ cgctx.pc_ret0 = -1;
+ /* Scouting faux-generate pass 0 */
+ if (bpf_jit_build_body(fp, 0, &cgctx, addrs))
+ /* We hit something illegal or unsupported. */
+ goto out;
+
+ /*
+ * Pretend to build prologue, given the features we've seen. This will
+ * update ctgtx.idx as it pretends to output instructions, then we can
+ * calculate total size from idx.
+ */
+ bpf_jit_build_prologue(fp, 0, &cgctx);
+ bpf_jit_build_epilogue(0, &cgctx);
+
+ proglen = cgctx.idx * 4;
+ alloclen = proglen + FUNCTION_DESCR_SIZE;
+ image = module_alloc(max_t(unsigned int, alloclen,
+ sizeof(struct work_struct)));
+ if (!image)
+ goto out;
+
+ code_base = image + (FUNCTION_DESCR_SIZE/4);
+
+ /* Code generation passes 1-2 */
+ for (pass = 1; pass < 3; pass++) {
+ /* Now build the prologue, body code & epilogue for real. */
+ cgctx.idx = 0;
+ bpf_jit_build_prologue(fp, code_base, &cgctx);
+ bpf_jit_build_body(fp, code_base, &cgctx, addrs);
+ bpf_jit_build_epilogue(code_base, &cgctx);
+
+ if (bpf_jit_enable > 1)
+ pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
+ proglen - (cgctx.idx * 4), cgctx.seen);
+ }
+
+ if (bpf_jit_enable > 1)
+ pr_info("flen=%d proglen=%u pass=%d image=%p\n",
+ flen, proglen, pass, image);
+
+ if (image) {
+ if (bpf_jit_enable > 1)
+ print_hex_dump(KERN_ERR, "JIT code: ",
+ DUMP_PREFIX_ADDRESS,
+ 16, 1, code_base,
+ proglen, false);
+
+ bpf_flush_icache(code_base, code_base + (proglen/4));
+ /* Function descriptor nastiness: Address + TOC */
+ ((u64 *)image)[0] = (u64)code_base;
+ ((u64 *)image)[1] = local_paca->kernel_toc;
+ fp->bpf_func = (void *)image;
+ }
+out:
+ kfree(addrs);
+ return;
+}
+
+static void jit_free_defer(struct work_struct *arg)
+{
+ module_free(NULL, arg);
+}
+
+/* run from softirq, we must use a work_struct to call
+ * module_free() from process context
+ */
+void bpf_jit_free(struct sk_filter *fp)
+{
+ if (fp->bpf_func != sk_run_filter) {
+ struct work_struct *work = (struct work_struct *)fp->bpf_func;
+
+ INIT_WORK(work, jit_free_defer);
+ schedule_work(work);
+ }
+}
^ permalink raw reply related
* [PATCH 4/4 net-next] bnx2: Fix endian swapping on firmware version string
From: Michael Chan @ 2011-07-21 0:55 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1311209725-10414-3-git-send-email-mchan@broadcom.com>
so that ethtool -i will display it correctly on big endian systems.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
---
drivers/net/bnx2.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 3ad9b70..4b2b570 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -56,8 +56,8 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
-#define DRV_MODULE_VERSION "2.1.10"
-#define DRV_MODULE_RELDATE "July 12, 2011"
+#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 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"
@@ -8097,7 +8097,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->fw_version[j++] = ' ';
for (i = 0; i < 3 && j < 28; i++) {
reg = bnx2_reg_rd_ind(bp, addr + i * 4);
- reg = swab32(reg);
+ reg = be32_to_cpu(reg);
memcpy(&bp->fw_version[j], ®, 4);
j += 4;
}
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH 3/4 net-next] cnic: Add VLAN ID as a parameter during netevent upcall
From: Michael Chan @ 2011-07-21 0:55 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1311209725-10414-2-git-send-email-mchan@broadcom.com>
The bnx2fc driver needs to handle netdev events on VLAN devices.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
---
drivers/net/cnic.c | 50 +++++++++++++++++++++++++-----------
drivers/net/cnic_if.h | 6 ++--
drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 8 +++++-
drivers/scsi/bnx2i/bnx2i_hwi.c | 8 +++++-
4 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 9be0c26..94a2e54 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -5334,6 +5334,27 @@ static struct cnic_dev *is_cnic_dev(struct net_device *dev)
return cdev;
}
+static void cnic_rcv_netevent(struct cnic_local *cp, unsigned long event,
+ u16 vlan_id)
+{
+ int if_type;
+
+ rcu_read_lock();
+ for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
+ struct cnic_ulp_ops *ulp_ops;
+ void *ctx;
+
+ ulp_ops = rcu_dereference(cp->ulp_ops[if_type]);
+ if (!ulp_ops || !ulp_ops->indicate_netevent)
+ continue;
+
+ ctx = cp->ulp_handle[if_type];
+
+ ulp_ops->indicate_netevent(ctx, event, vlan_id);
+ }
+ rcu_read_unlock();
+}
+
/**
* netdev event handler
*/
@@ -5342,7 +5363,6 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
{
struct net_device *netdev = ptr;
struct cnic_dev *dev;
- int if_type;
int new_dev = 0;
dev = cnic_from_netdev(netdev);
@@ -5372,20 +5392,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
cnic_ulp_start(dev);
}
- rcu_read_lock();
- for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
- struct cnic_ulp_ops *ulp_ops;
- void *ctx;
-
- ulp_ops = rcu_dereference(cp->ulp_ops[if_type]);
- if (!ulp_ops || !ulp_ops->indicate_netevent)
- continue;
-
- ctx = cp->ulp_handle[if_type];
-
- ulp_ops->indicate_netevent(ctx, event);
- }
- rcu_read_unlock();
+ cnic_rcv_netevent(cp, event, 0);
if (event == NETDEV_GOING_DOWN) {
cnic_ulp_stop(dev);
@@ -5401,6 +5408,19 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
goto done;
}
cnic_put(dev);
+ } else {
+ struct net_device *realdev;
+ u16 vid;
+
+ vid = cnic_get_vlan(netdev, &realdev);
+ if (realdev) {
+ dev = cnic_from_netdev(realdev);
+ if (dev) {
+ vid |= VLAN_TAG_PRESENT;
+ cnic_rcv_netevent(dev->cnic_priv, event, vid);
+ cnic_put(dev);
+ }
+ }
}
done:
return NOTIFY_DONE;
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index 642b9d5..fd54a6a 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -12,8 +12,8 @@
#ifndef CNIC_IF_H
#define CNIC_IF_H
-#define CNIC_MODULE_VERSION "2.5.6"
-#define CNIC_MODULE_RELDATE "July 12, 2011"
+#define CNIC_MODULE_VERSION "2.5.7"
+#define CNIC_MODULE_RELDATE "July 20, 2011"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
@@ -313,7 +313,7 @@ struct cnic_ulp_ops {
void (*cnic_stop)(void *ulp_ctx);
void (*indicate_kcqes)(void *ulp_ctx, struct kcqe *cqes[],
u32 num_cqes);
- void (*indicate_netevent)(void *ulp_ctx, unsigned long event);
+ void (*indicate_netevent)(void *ulp_ctx, unsigned long event, u16 vid);
void (*cm_connect_complete)(struct cnic_sock *);
void (*cm_close_complete)(struct cnic_sock *);
void (*cm_abort_complete)(struct cnic_sock *);
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 7a16ca1..9eebaeb 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -767,17 +767,23 @@ static void bnx2fc_destroy_timer(unsigned long data)
*
* @context: adapter structure pointer
* @event: event type
+ * @vlan_id: vlan id - associated vlan id with this event
*
* Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and
* NETDEV_CHANGE_MTU events
*/
-static void bnx2fc_indicate_netevent(void *context, unsigned long event)
+static void bnx2fc_indicate_netevent(void *context, unsigned long event,
+ u16 vlan_id)
{
struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
struct fc_lport *lport = hba->ctlr.lp;
struct fc_lport *vport;
u32 link_possible = 1;
+ /* Ignore vlans for now */
+ if (vlan_id != 0)
+ return;
+
if (!test_bit(BNX2FC_CREATE_DONE, &hba->init_done)) {
BNX2FC_MISC_DBG("driver not ready. event=%s %ld\n",
hba->netdev->name, event);
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 5c54a2d..372d30c 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -2386,14 +2386,20 @@ static void bnx2i_indicate_kcqe(void *context, struct kcqe *kcqe[],
* bnx2i_indicate_netevent - Generic netdev event handler
* @context: adapter structure pointer
* @event: event type
+ * @vlan_id: vlans id - associated vlan id with this event
*
* Handles four netdev events, NETDEV_UP, NETDEV_DOWN,
* NETDEV_GOING_DOWN and NETDEV_CHANGE
*/
-static void bnx2i_indicate_netevent(void *context, unsigned long event)
+static void bnx2i_indicate_netevent(void *context, unsigned long event,
+ u16 vlan_id)
{
struct bnx2i_hba *hba = context;
+ /* Ignore all netevent coming from vlans */
+ if (vlan_id != 0)
+ return;
+
switch (event) {
case NETDEV_UP:
if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH 1/4 net-next] cnic: Fix Context ID space calculation
From: Michael Chan @ 2011-07-21 0:55 UTC (permalink / raw)
To: davem; +Cc: netdev
Include FCoE CID space only for E2_PLUS devices. Remove old CID
offset adjustments that are no longer needed.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
---
drivers/net/cnic.c | 10 +---------
1 files changed, 1 insertions(+), 9 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index ea75f65..455fd0d 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -1172,7 +1172,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
cp->iro_arr = ethdev->iro_arr;
- cp->max_cid_space = MAX_ISCSI_TBL_SZ + BNX2X_FCOE_NUM_CONNECTIONS;
+ cp->max_cid_space = MAX_ISCSI_TBL_SZ;
cp->iscsi_start_cid = start_cid;
cp->fcoe_start_cid = start_cid + MAX_ISCSI_TBL_SZ;
@@ -1183,14 +1183,6 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
cp->fcoe_init_cid = 0x10;
}
- if (start_cid < BNX2X_ISCSI_START_CID) {
- u32 delta = BNX2X_ISCSI_START_CID - start_cid;
-
- cp->iscsi_start_cid = BNX2X_ISCSI_START_CID;
- cp->fcoe_start_cid += delta;
- cp->max_cid_space += delta;
- }
-
cp->iscsi_tbl = kzalloc(sizeof(struct cnic_iscsi) * MAX_ISCSI_TBL_SZ,
GFP_KERNEL);
if (!cp->iscsi_tbl)
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH 2/4 net-next] cnic: Wait for all Context IDs to be deleted before sending FCOE_DESTROY_FUNC
From: Michael Chan @ 2011-07-21 0:55 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1311209725-10414-1-git-send-email-mchan@broadcom.com>
Otherwise, the firmware will not respond and we'll have to wait for
timeout. Refactor the wait loop we already have into a separate
function for this purpose.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
---
drivers/net/cnic.c | 45 +++++++++++++++++++++++++++------------------
1 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 455fd0d..9be0c26 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2448,6 +2448,30 @@ static int cnic_bnx2x_fcoe_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
return ret;
}
+static void cnic_bnx2x_delete_wait(struct cnic_dev *dev, u32 start_cid)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ u32 i;
+
+ for (i = start_cid; i < cp->max_cid_space; i++) {
+ struct cnic_context *ctx = &cp->ctx_tbl[i];
+ int j;
+
+ while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
+ msleep(10);
+
+ for (j = 0; j < 5; j++) {
+ if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
+ break;
+ msleep(20);
+ }
+
+ if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
+ netdev_warn(dev->netdev, "CID %x not deleted\n",
+ ctx->cid);
+ }
+}
+
static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
{
struct fcoe_kwqe_destroy *req;
@@ -2456,6 +2480,8 @@ static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
int ret;
u32 cid;
+ cnic_bnx2x_delete_wait(dev, MAX_ISCSI_TBL_SZ);
+
req = (struct fcoe_kwqe_destroy *) kwqe;
cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid);
@@ -3930,7 +3956,6 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode)
static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- int i;
if (!cp->ctx_tbl)
return;
@@ -3938,23 +3963,7 @@ static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
if (!netif_running(dev->netdev))
return;
- for (i = 0; i < cp->max_cid_space; i++) {
- struct cnic_context *ctx = &cp->ctx_tbl[i];
- int j;
-
- while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
- msleep(10);
-
- for (j = 0; j < 5; j++) {
- if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
- break;
- msleep(20);
- }
-
- if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
- netdev_warn(dev->netdev, "CID %x not deleted\n",
- ctx->cid);
- }
+ cnic_bnx2x_delete_wait(dev, 0);
cancel_delayed_work(&cp->delete_task);
flush_workqueue(cnic_wq);
--
1.6.4.GIT
^ permalink raw reply related
* Re: [PATCH 1/2] igb: Allow extra 4 bytes on RX for vlan tags.
From: Jeff Kirsher @ 2011-07-21 1:21 UTC (permalink / raw)
To: Ben Greear; +Cc: Jesse Gross, netdev@vger.kernel.org, Duyck, Alexander H
In-Reply-To: <4E277267.8090702@candelatech.com>
[-- Attachment #1: Type: text/plain, Size: 3800 bytes --]
On Wed, 2011-07-20 at 17:27 -0700, Ben Greear wrote:
> On 07/20/2011 05:18 PM, Jesse Gross wrote:
> > On Thu, Feb 17, 2011 at 9:28 AM, Ben Greear<greearb@candelatech.com> wrote:
> >> On 02/17/2011 03:04 AM, Jeff Kirsher wrote:
> >>>
> >>> On Thu, Feb 10, 2011 at 13:59,<greearb@candelatech.com> wrote:
> >>>>
> >>>> From: Ben Greear<greearb@candelatech.com>
> >>>>
> >>>> This allows the NIC to receive 1518 byte (not counting
> >>>> FCS) packets when MTU is 1500, thus allowing 1500 MTU
> >>>> VLAN frames to be received. Please note that no VLANs
> >>>> were actually configured on the NIC...it was just acting
> >>>> as pass-through device.
> >>>>
> >>>> Signed-off-by: Ben Greear<greearb@candelatech.com>
> >>>> ---
> >>>> :100644 100644 58c665b... 30c9cc6... M drivers/net/igb/igb_main.c
> >>>> drivers/net/igb/igb_main.c | 5 +++--
> >>>> 1 files changed, 3 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
> >>>> index 58c665b..30c9cc6 100644
> >>>> --- a/drivers/net/igb/igb_main.c
> >>>> +++ b/drivers/net/igb/igb_main.c
> >>>> @@ -2281,7 +2281,8 @@ static int __devinit igb_sw_init(struct igb_adapter
> >>>> *adapter)
> >>>> adapter->rx_itr_setting = IGB_DEFAULT_ITR;
> >>>> adapter->tx_itr_setting = IGB_DEFAULT_ITR;
> >>>>
> >>>> - adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
> >>>> + adapter->max_frame_size = (netdev->mtu + ETH_HLEN + ETH_FCS_LEN
> >>>> + + VLAN_HLEN);
> >>>> adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
> >>>>
> >>>> spin_lock_init(&adapter->stats64_lock);
> >>>> @@ -4303,7 +4304,7 @@ static int igb_change_mtu(struct net_device
> >>>> *netdev, int new_mtu)
> >>>> {
> >>>> struct igb_adapter *adapter = netdev_priv(netdev);
> >>>> struct pci_dev *pdev = adapter->pdev;
> >>>> - int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
> >>>> + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
> >>>> u32 rx_buffer_len, i;
> >>>>
> >>>> if ((new_mtu< 68) || (max_frame> MAX_JUMBO_FRAME_SIZE)) {
> >>>
> >>> While testing this patch, validation found that the patch reduces the
> >>> maximum mtu size
> >>> by 4 bytes (reduces it from 9216 to 9212). This is not a desired side
> >>> effect of this patch.
> >>
> >> You could add handling for that case and have it act as it used to when
> >> new_mtu is greater than 9212?
> >>
> >> I tested e1000e and it worked w/out hacking at 1500 MTU, so maybe
> >> check how it does it?
> >
> > I just wanted to bring this up again to see if any progress had been
> > made. We were looking at this driver and trying to figure out the
> > best way to convert it to use the new vlan model but I'm not familiar
>
> I've been watching :)
>
> > enough with the hardware to know. It seems that all of the other
> > Intel drivers unconditionally add space for the vlan tag to the
> > receive buffer (and would therefore have similar effects as this
> > patch), is there something different about this card?
> >
> > I believe that Alex was working on something in this area (in the
> > context of one of my patches from a long time ago) but I'm not sure
> > what came of that.
>
> Truth is, I don't really see why it's a problem to decrease the
> maximum MTU slightly in order to make it work with VLANs.
>
> I'm not sure if there is some way to make it work with VLANs
> and not decrease the maximum MTU.
This was the reason this did not get accepted. I was looking into what
could be done so that we did not decease the maximum MTU, but I got
side-tracked and have not done anything on it in several months.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: Just one more byte, it is wafer thin...
From: Rick Jones @ 2011-07-21 0:52 UTC (permalink / raw)
To: netdev
In-Reply-To: <4E2764A0.90003@hp.com>
On 07/20/2011 04:28 PM, Rick Jones wrote:
> and got a somewhat unexpected result - I've no idea why then they both
> went up - perhaps it was sensing "high" occasionally even in the 4344
> byte request case.
That would seem to be the case? Back to defaults, ./configure'd netperf
with --enable-demo and have it print-out interim results every 250
milliseconds (or so)
root@use111814x:~/netperf-2.5.0# HDR="-P 1";for r in 4344 4345; do
netperf -D 0.25 -H mumble.3.21 -t TCP_RR $HDR -- -r ${r},1; HDR="-P 0"; done
MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to mumble.3.21 (mumble.3.21) port 0 AF_INET : histogram : demo : first
burst 0
Interim result: 5332.90 Trans/s over 0.28 seconds ending at 1311209347.312
Interim result: 6867.20 Trans/s over 0.25 seconds ending at 1311209347.562
Interim result: 14475.52 Trans/s over 0.25 seconds ending at 1311209347.813
Interim result: 14513.50 Trans/s over 0.25 seconds ending at 1311209348.063
Interim result: 14528.00 Trans/s over 0.25 seconds ending at 1311209348.313
Interim result: 8245.53 Trans/s over 0.44 seconds ending at 1311209348.753
Interim result: 13523.73 Trans/s over 0.25 seconds ending at 1311209349.003
Interim result: 13310.17 Trans/s over 0.26 seconds ending at 1311209349.259
Interim result: 8303.74 Trans/s over 0.40 seconds ending at 1311209349.660
Interim result: 14202.24 Trans/s over 0.25 seconds ending at 1311209349.910
Interim result: 8124.76 Trans/s over 0.44 seconds ending at 1311209350.347
Interim result: 14495.59 Trans/s over 0.25 seconds ending at 1311209350.597
Interim result: 14505.91 Trans/s over 0.25 seconds ending at 1311209350.847
Interim result: 13338.19 Trans/s over 0.27 seconds ending at 1311209351.119
Interim result: 7280.44 Trans/s over 0.46 seconds ending at 1311209351.577
Interim result: 14002.71 Trans/s over 0.25 seconds ending at 1311209351.827
Interim result: 6661.47 Trans/s over 0.53 seconds ending at 1311209352.353
Interim result: 4069.30 Trans/s over 0.41 seconds ending at 1311209352.762
Interim result: 10444.77 Trans/s over 0.35 seconds ending at 1311209353.110
Interim result: 9013.21 Trans/s over 0.29 seconds ending at 1311209353.399
Interim result: 6480.59 Trans/s over 0.35 seconds ending at 1311209353.747
Interim result: 13245.09 Trans/s over 0.25 seconds ending at 1311209353.997
Interim result: 12205.48 Trans/s over 0.30 seconds ending at 1311209354.294
Interim result: 5592.64 Trans/s over 0.55 seconds ending at 1311209354.840
Interim result: 6142.67 Trans/s over 0.59 seconds ending at 1311209355.430
Interim result: 11084.00 Trans/s over 0.25 seconds ending at 1311209355.680
Interim result: 14511.18 Trans/s over 0.25 seconds ending at 1311209355.930
Interim result: 14475.35 Trans/s over 0.25 seconds ending at 1311209356.181
Interim result: 7893.58 Trans/s over 0.46 seconds ending at 1311209356.639
Interim result: 14176.00 Trans/s over 0.25 seconds ending at 1311209356.889
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
16384 87380 4344 1 10.00 9907.27
16384 87380
now the 4345 byte request:
Interim result: 8712.99 Trans/s over 0.37 seconds ending at 1311209357.406
Interim result: 3344.24 Trans/s over 0.65 seconds ending at 1311209358.057
Interim result: 3495.28 Trans/s over 0.25 seconds ending at 1311209358.308
Interim result: 3457.05 Trans/s over 0.25 seconds ending at 1311209358.561
Interim result: 3315.55 Trans/s over 0.26 seconds ending at 1311209358.821
Interim result: 3340.47 Trans/s over 0.25 seconds ending at 1311209359.072
Interim result: 3343.81 Trans/s over 0.25 seconds ending at 1311209359.322
Interim result: 3373.45 Trans/s over 0.25 seconds ending at 1311209359.572
Interim result: 3292.31 Trans/s over 0.26 seconds ending at 1311209359.828
Interim result: 3328.17 Trans/s over 0.25 seconds ending at 1311209360.079
Interim result: 3373.07 Trans/s over 0.25 seconds ending at 1311209360.329
Interim result: 3431.75 Trans/s over 0.25 seconds ending at 1311209360.579
Interim result: 3324.45 Trans/s over 0.26 seconds ending at 1311209360.837
Interim result: 3347.82 Trans/s over 0.25 seconds ending at 1311209361.087
Interim result: 3327.10 Trans/s over 0.25 seconds ending at 1311209361.338
Interim result: 3337.22 Trans/s over 0.25 seconds ending at 1311209361.589
Interim result: 3444.56 Trans/s over 0.25 seconds ending at 1311209361.839
Interim result: 3336.91 Trans/s over 0.26 seconds ending at 1311209362.097
Interim result: 3323.07 Trans/s over 0.25 seconds ending at 1311209362.348
Interim result: 3422.15 Trans/s over 0.25 seconds ending at 1311209362.598
Interim result: 3327.81 Trans/s over 0.26 seconds ending at 1311209362.855
Interim result: 3312.43 Trans/s over 0.25 seconds ending at 1311209363.106
Interim result: 3346.22 Trans/s over 0.25 seconds ending at 1311209363.356
Interim result: 3426.75 Trans/s over 0.25 seconds ending at 1311209363.606
Interim result: 3304.44 Trans/s over 0.26 seconds ending at 1311209363.866
Interim result: 3466.26 Trans/s over 0.25 seconds ending at 1311209364.116
Interim result: 3299.97 Trans/s over 0.26 seconds ending at 1311209364.379
Interim result: 3360.99 Trans/s over 0.25 seconds ending at 1311209364.629
Interim result: 3402.76 Trans/s over 0.25 seconds ending at 1311209364.879
Interim result: 3389.28 Trans/s over 0.25 seconds ending at 1311209365.130
Interim result: 3360.94 Trans/s over 0.25 seconds ending at 1311209365.382
Interim result: 3319.58 Trans/s over 0.25 seconds ending at 1311209365.635
Interim result: 3440.41 Trans/s over 0.25 seconds ending at 1311209365.886
Interim result: 3386.75 Trans/s over 0.25 seconds ending at 1311209366.140
Interim result: 3337.23 Trans/s over 0.25 seconds ending at 1311209366.393
Interim result: 3329.40 Trans/s over 0.25 seconds ending at 1311209366.644
Interim result: 3328.29 Trans/s over 0.25 seconds ending at 1311209366.894
16384 87380 4345 1 10.00 3560.55
16384 87380
Still, is this suggesting that perhaps the adaptive
> bits are being a bit to aggressive about sensing high? Over what
> interval is that measurement supposed to be happening?
>
> rick jones
> --
> 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
* Re: [PATCH 1/2] igb: Allow extra 4 bytes on RX for vlan tags.
From: Ben Greear @ 2011-07-21 0:27 UTC (permalink / raw)
To: Jesse Gross; +Cc: Jeff Kirsher, netdev, Duyck, Alexander H
In-Reply-To: <CAEP_g=_o7nP2FCnPufyT44JZZ+Z+jkcVpSa8Qj3mjPn+MwRhXA@mail.gmail.com>
On 07/20/2011 05:18 PM, Jesse Gross wrote:
> On Thu, Feb 17, 2011 at 9:28 AM, Ben Greear<greearb@candelatech.com> wrote:
>> On 02/17/2011 03:04 AM, Jeff Kirsher wrote:
>>>
>>> On Thu, Feb 10, 2011 at 13:59,<greearb@candelatech.com> wrote:
>>>>
>>>> From: Ben Greear<greearb@candelatech.com>
>>>>
>>>> This allows the NIC to receive 1518 byte (not counting
>>>> FCS) packets when MTU is 1500, thus allowing 1500 MTU
>>>> VLAN frames to be received. Please note that no VLANs
>>>> were actually configured on the NIC...it was just acting
>>>> as pass-through device.
>>>>
>>>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>>>> ---
>>>> :100644 100644 58c665b... 30c9cc6... M drivers/net/igb/igb_main.c
>>>> drivers/net/igb/igb_main.c | 5 +++--
>>>> 1 files changed, 3 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
>>>> index 58c665b..30c9cc6 100644
>>>> --- a/drivers/net/igb/igb_main.c
>>>> +++ b/drivers/net/igb/igb_main.c
>>>> @@ -2281,7 +2281,8 @@ static int __devinit igb_sw_init(struct igb_adapter
>>>> *adapter)
>>>> adapter->rx_itr_setting = IGB_DEFAULT_ITR;
>>>> adapter->tx_itr_setting = IGB_DEFAULT_ITR;
>>>>
>>>> - adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
>>>> + adapter->max_frame_size = (netdev->mtu + ETH_HLEN + ETH_FCS_LEN
>>>> + + VLAN_HLEN);
>>>> adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
>>>>
>>>> spin_lock_init(&adapter->stats64_lock);
>>>> @@ -4303,7 +4304,7 @@ static int igb_change_mtu(struct net_device
>>>> *netdev, int new_mtu)
>>>> {
>>>> struct igb_adapter *adapter = netdev_priv(netdev);
>>>> struct pci_dev *pdev = adapter->pdev;
>>>> - int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
>>>> + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
>>>> u32 rx_buffer_len, i;
>>>>
>>>> if ((new_mtu< 68) || (max_frame> MAX_JUMBO_FRAME_SIZE)) {
>>>
>>> While testing this patch, validation found that the patch reduces the
>>> maximum mtu size
>>> by 4 bytes (reduces it from 9216 to 9212). This is not a desired side
>>> effect of this patch.
>>
>> You could add handling for that case and have it act as it used to when
>> new_mtu is greater than 9212?
>>
>> I tested e1000e and it worked w/out hacking at 1500 MTU, so maybe
>> check how it does it?
>
> I just wanted to bring this up again to see if any progress had been
> made. We were looking at this driver and trying to figure out the
> best way to convert it to use the new vlan model but I'm not familiar
I've been watching :)
> enough with the hardware to know. It seems that all of the other
> Intel drivers unconditionally add space for the vlan tag to the
> receive buffer (and would therefore have similar effects as this
> patch), is there something different about this card?
>
> I believe that Alex was working on something in this area (in the
> context of one of my patches from a long time ago) but I'm not sure
> what came of that.
Truth is, I don't really see why it's a problem to decrease the
maximum MTU slightly in order to make it work with VLANs.
I'm not sure if there is some way to make it work with VLANs
and not decrease the maximum MTU.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH 1/2] igb: Allow extra 4 bytes on RX for vlan tags.
From: Jesse Gross @ 2011-07-21 0:18 UTC (permalink / raw)
To: Ben Greear; +Cc: Jeff Kirsher, netdev, Duyck, Alexander H
In-Reply-To: <4D5D5AD8.5000802@candelatech.com>
On Thu, Feb 17, 2011 at 9:28 AM, Ben Greear <greearb@candelatech.com> wrote:
> On 02/17/2011 03:04 AM, Jeff Kirsher wrote:
>>
>> On Thu, Feb 10, 2011 at 13:59,<greearb@candelatech.com> wrote:
>>>
>>> From: Ben Greear<greearb@candelatech.com>
>>>
>>> This allows the NIC to receive 1518 byte (not counting
>>> FCS) packets when MTU is 1500, thus allowing 1500 MTU
>>> VLAN frames to be received. Please note that no VLANs
>>> were actually configured on the NIC...it was just acting
>>> as pass-through device.
>>>
>>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>>> ---
>>> :100644 100644 58c665b... 30c9cc6... M drivers/net/igb/igb_main.c
>>> drivers/net/igb/igb_main.c | 5 +++--
>>> 1 files changed, 3 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
>>> index 58c665b..30c9cc6 100644
>>> --- a/drivers/net/igb/igb_main.c
>>> +++ b/drivers/net/igb/igb_main.c
>>> @@ -2281,7 +2281,8 @@ static int __devinit igb_sw_init(struct igb_adapter
>>> *adapter)
>>> adapter->rx_itr_setting = IGB_DEFAULT_ITR;
>>> adapter->tx_itr_setting = IGB_DEFAULT_ITR;
>>>
>>> - adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
>>> + adapter->max_frame_size = (netdev->mtu + ETH_HLEN + ETH_FCS_LEN
>>> + + VLAN_HLEN);
>>> adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
>>>
>>> spin_lock_init(&adapter->stats64_lock);
>>> @@ -4303,7 +4304,7 @@ static int igb_change_mtu(struct net_device
>>> *netdev, int new_mtu)
>>> {
>>> struct igb_adapter *adapter = netdev_priv(netdev);
>>> struct pci_dev *pdev = adapter->pdev;
>>> - int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
>>> + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
>>> u32 rx_buffer_len, i;
>>>
>>> if ((new_mtu< 68) || (max_frame> MAX_JUMBO_FRAME_SIZE)) {
>>
>> While testing this patch, validation found that the patch reduces the
>> maximum mtu size
>> by 4 bytes (reduces it from 9216 to 9212). This is not a desired side
>> effect of this patch.
>
> You could add handling for that case and have it act as it used to when
> new_mtu is greater than 9212?
>
> I tested e1000e and it worked w/out hacking at 1500 MTU, so maybe
> check how it does it?
I just wanted to bring this up again to see if any progress had been
made. We were looking at this driver and trying to figure out the
best way to convert it to use the new vlan model but I'm not familiar
enough with the hardware to know. It seems that all of the other
Intel drivers unconditionally add space for the vlan tag to the
receive buffer (and would therefore have similar effects as this
patch), is there something different about this card?
I believe that Alex was working on something in this area (in the
context of one of my patches from a long time ago) but I'm not sure
what came of that.
^ permalink raw reply
* Re: [patch net-next-2.6 37/47] igb: do vlan cleanup
From: Jesse Gross @ 2011-07-20 23:58 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, shemminger, eric.dumazet, greearb, mirqus,
jeffrey.t.kirsher, jesse.brandeburg, peter.p.waskiewicz.jr,
bruce.w.allan, carolyn.wyborny, donald.c.skidmore, gregory.v.rose,
alexander.h.duyck, john.ronciak, e1000-devel
In-Reply-To: <20110720191045.GD2688@minipsycho.redhat.com>
On Wed, Jul 20, 2011 at 12:10 PM, Jiri Pirko <jpirko@redhat.com> wrote:
> Wed, Jul 20, 2011 at 07:35:33PM CEST, jesse@nicira.com wrote:
>>On Wed, Jul 20, 2011 at 7:54 AM, Jiri Pirko <jpirko@redhat.com> wrote:
>>> @@ -2943,7 +2944,7 @@ static void igb_rlpml_set(struct igb_adapter *adapter)
>>> struct e1000_hw *hw = &adapter->hw;
>>> u16 pf_id = adapter->vfs_allocated_count;
>>>
>>> - if (adapter->vlgrp)
>>> + if (igb_vlan_used(adapter))
>>> max_frame_size += VLAN_TAG_SIZE;
>>
>>There are similar issues here as with the VF driver. I think you're
>>also confusing vlan acceleration with vlan filtering. If no vlan
>>filters are in use but the card is in promiscuous mode, the buffer
>>will be undersized and we lose tagged packets.
>
> I'm certainly not confusing vlan accel and filtering. Here is the
> intension is the behaviour remains intact as well. I believe it's true.
I believe the underlying issue for all three of these threads is the
same, so I'll just respond to them all here.
I agree that this doesn't change the behavior of the driver but I
don't think that should be the goal. When I originally designed this
new vlan model my intention was to eliminate a whole class of driver
bugs that I was repeatedly hitting in various forms. In the example
above, if you run tcpdump on this device without configuring a vlan
group on it then you will see that MTU sized packets are missing
because the receive buffer was undersized.
The common theme for these problems is that they all occur in
situations where vlans are not configured on the device and the driver
does something different as a result of this. The solution was to
prevent drivers from changing their behavior in such situations by
completely removing the concept of a vlan group from them and letting
the networking core tell them when to make the changes instead of
doing it implicitly. That's why I don't see the fact that this change
essentially emulates the knowledge of configuring a group to be a
plus. By the way, plenty of your other patches change the behavior of
the drivers - on any of the NICs that always enable stripping, try
running tcpdump on the interface without configuring a vlan group.
Before the change you will see that tags have disappeared and
afterwards the tags are intact. So I think that changing the behavior
of drivers in this regard is a positive thing.
As an aside, thank you for taking the time to work on all of these
drivers. The only reason why I'm complaining about these few drivers
is because I'd like to close the door on this class of problems, which
is finally in reach thanks to your work.
^ permalink raw reply
* Just one more byte, it is wafer thin...
From: Rick Jones @ 2011-07-20 23:28 UTC (permalink / raw)
To: netdev
One of the netperf scripts I run from time to time is the
packet_byte_script (doc/examples/packet_byte_script in the netperf
source tree, though I tweaked it locally to use omni output selectors).
The goal of that script is to measure the incremental cost of sending
another byte and/or another TCP segment. Among other things, it runs RR
tests where the request or response size is incremented. It starts at 1
byte, doubles until it would exceed the MSS, then does 1MSS, 1MSS+1,
2MSS, 2MSS+1 and 3MSS, 3MSS+1.
I recently ran it between a pair of dual-processor X5650 based systems
with 10GbE NICs based on Mellanox MT26438 running as a 10GbE interface.
The kernel is 2.6.38-8-server (maverick) and the driver info is:
# ethtool -i eth2
driver: mlx4_en (HP_0200000003)
version: 1.5.1.6 (August 2010)
firmware-version: 2.7.9294
bus-info: 0000:05:00.0
(yes, that HP_mumble does broach the possibility of a local fubar. i'd
try a pure upstream myself but the systems at my disposal are somewhat
locked-down, i'm hoping someone with a "pure" environment can reproduce
the result, or not)
The full output can be seen at:
ftp://ftp.netperf.org/netperf/misc/sl390_NC543i_mlx4_en_1.5.1.6_Ubuntu_11.04_A5800_56C_to_same_pab_1500mtu_20110719.csv
I wasn't entirely sure what TSO and LRO/GRO would mean for the script,
at first I thought I wouldn't get the +1 trip down the stack, but the
transaction rates all looked reasonably "sane" until the 3MSS to 3MSS+1
transition, when the transaction rate dropped by something like 70%. And
stayed there as the request size was increased further in other testing.
I looked at a tcpdump trace on the sending and receiving side - LRO/GRO
had coalesced segments into the full request size. On the sending side
though, I was seeing one segment of 3MSS and one of one byte. At first
I thought that perhaps something was fubar with cwnd, but looking at
traces for 2MSS(+1) and 1MSS(+1) I saw that is just what TSO does - only
send integer multiples of the MSS as TSO. So, while that does
interesting things to the service demand for a given transaction size,
it probably wasn't the culprit.
It would seem that the adaptive-rx was. Previously, the coalescing
settings on the receiver (netserver side) were:
# ethtool -c eth2
Coalesce parameters for eth2:
Adaptive RX: on TX: off
stats-block-usecs: 0
sample-interval: 0
pkt-rate-low: 400000
pkt-rate-high: 450000
rx-usecs: 16
rx-frames: 44
rx-usecs-irq: 0
rx-frames-irq: 0
tx-usecs: 0
tx-frames: 0
tx-usecs-irq: 0
tx-frames-irq: 0
rx-usecs-low: 0
rx-frame-low: 0
tx-usecs-low: 0
tx-frame-low: 0
rx-usecs-high: 128
rx-frame-high: 0
tx-usecs-high: 0
tx-frame-high: 0
and netperf would look like:
# HDR="-P 1";for r in 4344 4345; do netperf -H mumble.3.21 -t TCP_RR
$HDR -- -r ${r},1; HDR="-P 0"; done
MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to mumble.3.21 (mumble.3.21) port 0 AF_INET : histogram : first burst 0
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
16384 87380 4344 1 10.00 10030.37
16384 87380
16384 87380 4345 1 10.00 3406.62
16384 87380
when I switched adaptive rx off via ethtool, the drop largely went away:
# HDR="-P 1";for r in 4344 4345; do netperf -H mumble.3.21 -t TCP_RR
$HDR -- -r ${r},1; HDR="-P 0"; done
MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to mumble.3.21 (mumble.3.21) port 0 AF_INET : histogram : first burst 0
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
16384 87380 4344 1 10.00 11167.48
16384 87380
16384 87380 4345 1 10.00 10460.02
16384 87380
Now, at 11000 transactions per second, even with the request being 4
packets, that is still < 55000 packets per second, so presumably
everything should have stayed at "_low" right? Just for grins, I put
adaptive coalescing on again and set rx-usecs-high to 64 and ran those
two points again:
# HDR="-P 1";for r in 4344 4345; do netperf -H mumble.3.21 -t TCP_RR
$HDR -- -r ${r},1; HDR="-P 0"; done
MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to mumble.3.21 (mumble.3.21) port 0 AF_INET : histogram : first burst 0
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
16384 87380 4344 1 10.00 11143.07
16384 87380
16384 87380 4345 1 10.00 5790.48
16384 87380
and just to be completely pedantic about it, set rx-usecs-high to 0:
# HDR="-P 1";for r in 4344 4345; do netperf -H mumble.3.21 -t TCP_RR
$HDR -- -r ${r},1; HDR="-P 0"; done
MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET
to mumble.3.21 (mumble.3.21) port 0 AF_INET : histogram : first burst 0
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
16384 87380 4344 1 10.00 14274.03
16384 87380
16384 87380 4345 1 10.00 13697.11
16384 87380
and got a somewhat unexpected result - I've no idea why then they both
went up - perhaps it was sensing "high" occasionally even in the 4344
byte request case. Still, is this suggesting that perhaps the adaptive
bits are being a bit to aggressive about sensing high? Over what
interval is that measurement supposed to be happening?
rick jones
^ permalink raw reply
* Re: [PATCH] iproute2: Remove "monitor" from "ip route help" output
From: Stephen Hemminger @ 2011-07-20 23:04 UTC (permalink / raw)
To: Andreas Henriksson; +Cc: netdev, martin f krafft, 537681
In-Reply-To: <20110720150814.GA12025@amd64.fatal.se>
On Wed, 20 Jul 2011 17:08:14 +0200
Andreas Henriksson <andreas@fatal.se> wrote:
> $ ip route help 2>&1 | grep monitor
> ip route { add | del | change | append | replace | monitor } ROUTE
> $ ip route monitor
> Command "monitor" is unknown, try "ip route help".
>
> (I guess what was really intended is "ip monitor route", so just remove
> the argument from the help output.)
>
> Originally reported by martin f krafft at http://bugs.debian.org/537681
>
> While at it, also drop all non-existant (route,link,netns) monitor
> arguments from the ip(8) man page.
>
> Signed-off-by: Andreas Henriksson <andreas@fatal.se>
Applied
^ permalink raw reply
* Re: [PATCH] Fix error decoding router advertisements netlink messages
From: Stephen Hemminger @ 2011-07-20 23:04 UTC (permalink / raw)
To: Andreas Henriksson; +Cc: netdev, Christoph Biedl
In-Reply-To: <1311151281-25479-1-git-send-email-andreas@fatal.se>
On Wed, 20 Jul 2011 10:41:21 +0200
Andreas Henriksson <andreas@fatal.se> wrote:
> From: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
>
> The "ip monitor" command does properly decode the "preferred" and
> "valid" lifetime records in router advertisements from netlink
> messages.
>
> For more details see http://bugs.debian.org/634170
>
> Signed-off-by: Andreas Henriksson <andreas@fatal.se>
Applied
^ permalink raw reply
* Re: [PATCH] rtlwifi: Convert printks to pr_<level>
From: Larry Finger @ 2011-07-20 22:45 UTC (permalink / raw)
To: Joe Perches
Cc: Chaoming Li, John W. Linville, linux-wireless, netdev,
linux-kernel
In-Reply-To: <b57f00fc1d0947443aa1830c11c288e78924af44.1311177059.git.joe@perches.com>
On 07/20/2011 10:51 AM, Joe Perches wrote:
> Use the current logging styles.
> Add pr_fmt where appropriate.
> Remove now unnecessary prefixes from printks.
> Convert hard coded prefix to __func__.
> Add a missing "\n" to a format.
>
> Signed-off-by: Joe Perches<joe@perches.com>
> ---
> drivers/net/wireless/rtlwifi/base.c | 9 ++-
> drivers/net/wireless/rtlwifi/cam.c | 4 +-
> drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 5 +-
> drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 69 ++++++++------------
> drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 11 ++-
> drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 8 +-
> drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 10 ++--
> drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 5 +-
> drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 4 +-
> drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 6 +-
> drivers/net/wireless/rtlwifi/usb.c | 12 ++--
> 11 files changed, 72 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
> index bc13533..d88e405 100644
> --- a/drivers/net/wireless/rtlwifi/base.c
> +++ b/drivers/net/wireless/rtlwifi/base.c
> @@ -27,6 +27,8 @@
> *
> *****************************************************************************/
ACKed-by: Larry Finger <Larry.Finger@lwfinger.net>
^ permalink raw reply
* Re: [PATCH] iproute2: Auto-detect the presence of setns in libc
From: Stephen Hemminger @ 2011-07-20 22:16 UTC (permalink / raw)
To: Dan McGee; +Cc: Eric W. Biederman, netdev
In-Reply-To: <CAEik5nOO9KQoEdvPUGwLBDJqOP9OWgz=G-3KMyvwiu4nwoyb=g@mail.gmail.com>
On Fri, 15 Jul 2011 19:34:04 -0500
Dan McGee <dan@archlinux.org> wrote:
> On Fri, Jul 15, 2011 at 7:26 PM, Eric W. Biederman
> <ebiederm@xmission.com> wrote:
> >
> > If libc has setns present use that version instead of
> > rolling the syscall wrapper by hand.
> >
I am more inclined to get rid of the wrapper completely
and just not put setns support in if libc doesn't support it.
^ permalink raw reply
* Re: NIC driver r8168 with r8169 for RTL8111/8168B and DGE-528T together
From: Danie Wessels @ 2011-07-20 22:11 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20110720122206.73898673@nehalam.ftrdhcpuser.net>
On 07/20/2011 09:22 PM, Stephen Hemminger wrote:
> On Wed, 20 Jul 2011 12:44:40 +0200
> Danie Wessels<dawessels@telkomsa.net> wrote:
>
>> I would like to use my onboard NIC (eth0) with its r8168 driver from
>> RealTek together with my D-Link NIC (eth4=eth1) with its r8169 default
>> driver from the install.
>
> The kernel developers do not support the use of out of tree
> vendor drivers. If there is some reason the default kernel driver does
> not work for your hardware, that is a bug that should be reported and
> it will get fixed.
>
I understand from Ubuntu forum that this bug (#347711) with the r8169
driver for the RTL8111/8168B is in the Will-not-fix state due to
(hardware?) it not being supported any more.
That leaves a number of us with little options.
.> Remove the 8168 PCI IDs from the r8169 driver and you should be set.
gr8. I can give that a try...8^0 (some more hints....?)
.>It ought to be supported by the kernel r8169 driver.
See bugs listed on Ubuntu:
https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.22/+bug/141343
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/221499
https://bugs.launchpad.net/linux/+bug/347711
And 0n Bug #347711
linux-kernel-bugs #12411
Duplicates of this bug
Bug #76489
Bug #347670
.> Which problem(s) do you have with it ?
No communication to outside devices. I can not ping my router through it
but can ping its IP.
What can I do now or where should I report it or how can I help?
RTFM 4 rules.d = where?
--
Dankie
Danie Wessels
^ permalink raw reply
* Re: sch_generic warn_on (timed out)
From: Francois Romieu @ 2011-07-20 21:53 UTC (permalink / raw)
To: davej; +Cc: David Miller, netdev
In-Reply-To: <20110711.141701.1453197953333902027.davem@davemloft.net>
David Miller <davem@davemloft.net> :
[...]
> > duping all others against. It seems to be showing up on a variety of different
> > hardware (r8169, atl1c, ipheth, e1000e, 8139too). Do all these drivers need
> > fixing ? or is it just 'crap hardware' ?
The r8169 driver has seen driver bugs, poorly supported hardware,
"interesting" hardware, evolving hardware, false alarm reports, crappy
maintainership and almost anything one can think of (as long as you do
not think about public datasheets or errata).
[...]
> I would track this on a per-device basis if I were you, instead of
> combining them all into one super-bug.
+1 +1 +1
One could almost split the r8169 problems further by XID, then eventually
by platform.
--
Ueimor
^ permalink raw reply
* Re: [patch net-next-2.6 16/47] enic: do vlan cleanup
From: vkolluri @ 2011-07-20 21:59 UTC (permalink / raw)
To: Jiri Pirko, netdev
Cc: davem, shemminger, eric.dumazet, greearb, mirqus, benve, roprabhu,
David (dwang2)
In-Reply-To: <1311173689-17419-17-git-send-email-jpirko@redhat.com>
These changes look good. Thanks Jiri.
-Vasanthy
On 7/20/11 7:54 AM, "Jiri Pirko" <jpirko@redhat.com> wrote:
> - unify vlan and nonvlan rx path
> - kill enic->vlan_group and enic_vlan_rx_register
>
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
> ---
> drivers/net/enic/enic.h | 1 -
> drivers/net/enic/enic_main.c | 32 ++++++--------------------------
> 2 files changed, 6 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
> index f0b062b..ce76d9a 100644
> --- a/drivers/net/enic/enic.h
> +++ b/drivers/net/enic/enic.h
> @@ -94,7 +94,6 @@ struct enic {
> ____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
> spinlock_t wq_lock[ENIC_WQ_MAX];
> unsigned int wq_count;
> - struct vlan_group *vlan_group;
> u16 loop_enable;
> u16 loop_tag;
>
> diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
> index e25800f..67a27cd 100644
> --- a/drivers/net/enic/enic_main.c
> +++ b/drivers/net/enic/enic_main.c
> @@ -1029,14 +1029,6 @@ static void enic_set_rx_mode(struct net_device *netdev)
> }
> }
>
> -/* rtnl lock is held */
> -static void enic_vlan_rx_register(struct net_device *netdev,
> - struct vlan_group *vlan_group)
> -{
> - struct enic *enic = netdev_priv(netdev);
> - enic->vlan_group = vlan_group;
> -}
> -
> /* netif_tx_lock held, BHs disabled */
> static void enic_tx_timeout(struct net_device *netdev)
> {
> @@ -1264,23 +1256,13 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
>
> skb->dev = netdev;
>
> - if (vlan_stripped) {
> -
> - if (netdev->features & NETIF_F_GRO)
> - vlan_gro_receive(&enic->napi[q_number],
> - enic->vlan_group, vlan_tci, skb);
> - else
> - vlan_hwaccel_receive_skb(skb,
> - enic->vlan_group, vlan_tci);
> + if (vlan_stripped)
> + __vlan_hwaccel_put_tag(skb, vlan_tci);
>
> - } else {
> -
> - if (netdev->features & NETIF_F_GRO)
> - napi_gro_receive(&enic->napi[q_number], skb);
> - else
> - netif_receive_skb(skb);
> -
> - }
> + if (netdev->features & NETIF_F_GRO)
> + napi_gro_receive(&enic->napi[q_number], skb);
> + else
> + netif_receive_skb(skb);
> } else {
>
> /* Buffer overflow
> @@ -2124,7 +2106,6 @@ static const struct net_device_ops
> enic_netdev_dynamic_ops = {
> .ndo_set_multicast_list = enic_set_rx_mode,
> .ndo_set_mac_address = enic_set_mac_address_dynamic,
> .ndo_change_mtu = enic_change_mtu,
> - .ndo_vlan_rx_register = enic_vlan_rx_register,
> .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
> .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
> .ndo_tx_timeout = enic_tx_timeout,
> @@ -2146,7 +2127,6 @@ static const struct net_device_ops enic_netdev_ops = {
> .ndo_set_rx_mode = enic_set_rx_mode,
> .ndo_set_multicast_list = enic_set_rx_mode,
> .ndo_change_mtu = enic_change_mtu,
> - .ndo_vlan_rx_register = enic_vlan_rx_register,
> .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
> .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
> .ndo_tx_timeout = enic_tx_timeout,
^ permalink raw reply
* Re: [PATCH] rtlwifi: Convert printks to pr_<level>
From: Joe Perches @ 2011-07-20 22:04 UTC (permalink / raw)
To: Larry Finger
Cc: Chaoming Li, John W. Linville, linux-wireless, netdev,
linux-kernel
In-Reply-To: <4E27048F.9090004@lwfinger.net>
On Wed, 2011-07-20 at 11:38 -0500, Larry Finger wrote:
> On 07/20/2011 10:51 AM, Joe Perches wrote:
> > Use the current logging styles.
> > Add pr_fmt where appropriate.
> > Remove now unnecessary prefixes from printks.
> > Convert hard coded prefix to __func__.
> > Add a missing "\n" to a format.
[]
> In general these look good, but why not define pr_fmt in rtlwifi/wifi.h. That
> header is used by every source file, and you only need the define once.
Because that's not the first #include in every file.
The #define pr_fmt has to be before anything that
includes kernel.h so it's safest/best to have it
be the first thing in the file.
At some point in the next year or so, all of the
uses of:
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
should be removed and that should become the default.
cheers, Joe
^ permalink raw reply
* RE: [PATCH 3/3] wireless: mwifiex: print hw address via %pM
From: Bing Zhao @ 2011-07-20 21:46 UTC (permalink / raw)
To: Andy Shevchenko,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, "John W. Lin
In-Reply-To: <8f12d3ad71585e863084560b227534a4b9e4af54.1311162926.git.andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Hi Andy,
Thanks for the patch.
> -----Original Message-----
> From: Andy Shevchenko [mailto:andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org]
> Sent: Wednesday, July 20, 2011 6:35 AM
> To: linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; John W. Linville; linux-
> kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: Andy Shevchenko; Bing Zhao
> Subject: [PATCH 3/3] wireless: mwifiex: print hw address via %pM
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> Cc: Bing Zhao <bzhao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
Acked-by: Bing Zhao <bzhao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
Thanks,
Bing
> ---
> drivers/net/wireless/mwifiex/debugfs.c | 33 +++++++------------------------
> 1 files changed, 8 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
> index 1bcf9ea..d26a78b 100644
> --- a/drivers/net/wireless/mwifiex/debugfs.c
> +++ b/drivers/net/wireless/mwifiex/debugfs.c
> @@ -216,28 +216,19 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
> p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
> p += sprintf(p, "media_state=\"%s\"\n",
> (!priv->media_connected ? "Disconnected" : "Connected"));
> - p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
> - netdev->dev_addr[0], netdev->dev_addr[1],
> - netdev->dev_addr[2], netdev->dev_addr[3],
> - netdev->dev_addr[4], netdev->dev_addr[5]);
> + p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
>
> if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
> p += sprintf(p, "multicast_count=\"%d\"\n",
> netdev_mc_count(netdev));
> p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
> - p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
> - info.bssid[0], info.bssid[1],
> - info.bssid[2], info.bssid[3],
> - info.bssid[4], info.bssid[5]);
> + p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
> p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
> p += sprintf(p, "region_code = \"%02x\"\n", info.region_code);
>
> netdev_for_each_mc_addr(ha, netdev)
> - p += sprintf(p, "multicast_address[%d]="
> - "\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++,
> - ha->addr[0], ha->addr[1],
> - ha->addr[2], ha->addr[3],
> - ha->addr[4], ha->addr[5]);
> + p += sprintf(p, "multicast_address[%d]=\"%pM\"\n",
> + i++, ha->addr);
> }
>
> p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
> @@ -451,26 +442,18 @@ mwifiex_debug_read(struct file *file, char __user *ubuf,
> if (info.tx_tbl_num) {
> p += sprintf(p, "Tx BA stream table:\n");
> for (i = 0; i < info.tx_tbl_num; i++)
> - p += sprintf(p, "tid = %d, "
> - "ra = %02x:%02x:%02x:%02x:%02x:%02x\n",
> - info.tx_tbl[i].tid, info.tx_tbl[i].ra[0],
> - info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2],
> - info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4],
> - info.tx_tbl[i].ra[5]);
> + p += sprintf(p, "tid = %d, ra = %pM\n",
> + info.tx_tbl[i].tid, info.tx_tbl[i].ra);
> }
>
> if (info.rx_tbl_num) {
> p += sprintf(p, "Rx reorder table:\n");
> for (i = 0; i < info.rx_tbl_num; i++) {
> -
> - p += sprintf(p, "tid = %d, "
> - "ta = %02x:%02x:%02x:%02x:%02x:%02x, "
> + p += sprintf(p, "tid = %d, ta = %pM, "
> "start_win = %d, "
> "win_size = %d, buffer: ",
> info.rx_tbl[i].tid,
> - info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1],
> - info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3],
> - info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5],
> + info.rx_tbl[i].ta,
> info.rx_tbl[i].start_win,
> info.rx_tbl[i].win_size);
>
> --
> 1.7.5.4
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] net: vlan: fix compile breakage from 69ecca8
From: Randy Dunlap @ 2011-07-20 21:06 UTC (permalink / raw)
To: David Lamparter
Cc: Stephen Rothwell, netdev, linux-next, linux-kernel, linux-driver,
Anirban Chakraborty, David S. Miller
In-Reply-To: <1311191033-714631-1-git-send-email-equinox@diac24.net>
On Wed, 20 Jul 2011 21:43:53 +0200 David Lamparter wrote:
> well, there was too much wood to see the tree and I messed up the
> configuration dependencies. let's make it work with unset
> CONFIG_VLAN_8021Q and remove the second definition of vlan_find_dev.
>
> Signed-off-by: David Lamparter <equinox@diac24.net>
> Cc: linux-driver@qlogic.com
> Cc: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Randy Dunlap <rdunlap@xenotime.net>
Reported-by: Randy Dunlap <rdunlap@xenotime.net>
Acked-by: Randy Dunlap <rdunlap@xenotime.net>
Thanks.
> ---
> sorry for the mess-up... compiled with CONFIG_VLAN_8021Q=n,m and y
> this time; don't have qlcnic hw to test.
>
> drivers/net/qlcnic/qlcnic_main.c | 4 +++-
> include/linux/if_vlan.h | 5 -----
> 2 files changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
> index 3579229..a2c39e9 100644
> --- a/drivers/net/qlcnic/qlcnic_main.c
> +++ b/drivers/net/qlcnic/qlcnic_main.c
> @@ -4198,13 +4198,15 @@ static void
> qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event)
> {
> struct qlcnic_adapter *adapter = netdev_priv(netdev);
> - struct vlan_group *grp;
> + struct vlan_group *grp = NULL;
> struct net_device *dev;
> u16 vid;
>
> qlcnic_config_indev_addr(adapter, netdev, event);
>
> +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
> grp = rcu_dereference_rtnl(netdev->vlgrp);
> +#endif
> if (!grp)
> return;
>
> diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
> index bc03e40..dbe41dc 100644
> --- a/include/linux/if_vlan.h
> +++ b/include/linux/if_vlan.h
> @@ -135,11 +135,6 @@ vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
> unsigned int vlan_tci);
>
> #else
> -static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
> - u16 vlan_id)
> -{
> - return NULL;
> -}
>
> static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
> {
> --
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
^ permalink raw reply
* Re: [patch] skbuff: use kfree_skb() instead of kfree()
From: Julie Sullivan @ 2011-07-20 21:03 UTC (permalink / raw)
To: Julia Lawall
Cc: Eric Dumazet, Dan Carpenter, Shirley Ma, David S. Miller,
Michał Mirosław, open list:NETWORKING [GENERAL],
kernel-janitors
In-Reply-To: <Pine.LNX.4.64.1107201035270.24382@ask.diku.dk>
>> > > Also, dont forget to say its a patch for net-next-2.6
>> >
>> > If you're using linux-next, is there a way to tell which tree a
>> > patch came from? Obviously in this case it's core networking, but
>> > in other cases how does that work?
>>
>> In this particular case, David will know for sure since patch is very
>> recent, but I wanted to make a general advice.
>>
>> Keep in mind David has to review dozens of patches _per_ day, so netdev
>> related patches need some extra cooperation from submitters to help the
>> maintainer.
>>
>> This extra cooperation means to test the patch on either net-next-2.6 or
>> net-2.6 tree ;)
>
> Maybe there is some way to integrate such a suggestion in get_maintainers
> or checkpatch? Otherwise, those who work on the code in a more breadth
> first way don't have much chance of knowing or remembering this advice.
>
> julia
I think Julia's observation is really on the nail, I wish there were
some way of doing this? If new or random testers or reviewers out
there aren't tracking/following a particular tree/project already -
i.e. if they don't _know_ beforehand, aren't they going to just assume
using linux-next is correct (at least that's what I do)?
Knowing what branch to most productively test patches against
beforehand might encourage more testers and submissions and also could
make maintainer's jobs a bit easier.
Cheers
Julie
^ permalink raw reply
* Re: NIC driver r8168 with r8169 for RTL8111/8168B and DGE-528T together
From: Francois Romieu @ 2011-07-20 20:30 UTC (permalink / raw)
To: Danie Wessels; +Cc: netdev
In-Reply-To: <4E26B198.4020606@telkomsa.net>
Danie Wessels <dawessels@telkomsa.net> :
[...]
> I would like to use my onboard NIC (eth0) with its r8168 driver from
> RealTek together with my D-Link NIC (eth4=eth1) with its r8169
> default driver from the install. Sepatately they seem to work...but
> I would like a firewall set up with NAT and had it before I
> "upgraded". ;^)
Remove the 8168 PCI IDs from the r8169 driver and you should be set.
[...]
> [ 1.486546] r8169 0000:03:00.0: eth0: RTL8168b/8111b at
> 0xf8024000, 00:1c:c0:a7:03:49, XID 98500000 IRQ 43
It ought to be supported by the kernel r8169 driver.
Which problem(s) do you have with it ?
--
Ueimor
^ 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