* [PATCH v2 3/7] coccinelle: add xxxsetbitsXX converting spatch
From: Corentin Labbe @ 2018-09-24 19:04 UTC (permalink / raw)
To: Gilles.Muller, Julia.Lawall, agust, airlied, alexandre.torgue,
alistair, benh, carlo, davem, galak, joabreu, khilman,
maxime.ripard, michal.lkml, mpe, mporter, narmstrong,
nicolas.palix, oss, paulus, peppe.cavallaro, tj, vitb, wens
Cc: cocci, dri-devel, linux-amlogic, linux-arm-kernel, linux-ide,
linux-kernel, linuxppc-dev, netdev, Corentin Labbe
In-Reply-To: <1537815856-31728-1-git-send-email-clabbe@baylibre.com>
This patch add a spatch which convert all open coded of setbits32/clrbits32/clrsetbits32
and their 64 bits counterparts.
Note that 64 and 32_relaxed are generated via
cp scripts/coccinelle/misc/setbits32.cocci scripts/coccinelle/misc/setbits32_relaxed.cocci
sed -i 's,readl,readl_relaxed,' scripts/coccinelle/misc/setbits32_relaxed.cocci
sed -i 's,writel,writel_relaxed,' scripts/coccinelle/misc/setbits32_relaxed.cocci
sed -i 's,setbits_le32,setbits_le32_relaxed,g' scripts/coccinelle/misc/setbits32_relaxed.cocci
sed -i 's,clrbits_le32,clrbits_le32_relaxed,g' scripts/coccinelle/misc/setbits32_relaxed.cocci
cp scripts/coccinelle/misc/setbits32.cocci scripts/coccinelle/misc/setbits64.cocci
sed -i 's,readl,readq,' scripts/coccinelle/misc/setbits64.cocci
sed -i 's,writel,writeq,' scripts/coccinelle/misc/setbits64.cocci
sed -i 's,le32,le64,' scripts/coccinelle/misc/setbits64.cocci
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
scripts/add_new_include_in_source.py | 61 +++
scripts/coccinelle/misc/setbits32.cocci | 487 ++++++++++++++++++++++++
scripts/coccinelle/misc/setbits32_relaxed.cocci | 487 ++++++++++++++++++++++++
scripts/coccinelle/misc/setbits64.cocci | 487 ++++++++++++++++++++++++
scripts/coccinelle/misc/setbits_dev.cocci | 235 ++++++++++++
5 files changed, 1757 insertions(+)
create mode 100755 scripts/add_new_include_in_source.py
create mode 100644 scripts/coccinelle/misc/setbits32.cocci
create mode 100644 scripts/coccinelle/misc/setbits32_relaxed.cocci
create mode 100644 scripts/coccinelle/misc/setbits64.cocci
create mode 100644 scripts/coccinelle/misc/setbits_dev.cocci
diff --git a/scripts/add_new_include_in_source.py b/scripts/add_new_include_in_source.py
new file mode 100755
index 000000000000..a43ccfbf9921
--- /dev/null
+++ b/scripts/add_new_include_in_source.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+
+# add <linux/setbits.h>
+
+import os, sys
+import re
+import shutil
+
+if len(sys.argv) < 2:
+ print("Usage: %s pathtosourcefile" % (sys.argv[0]))
+ sys.exit(1)
+
+found_global_headers = False
+found_local_headers = False
+#first check it does already here
+with open(sys.argv[1], 'r') as fp:
+ for line in fp:
+ if re.search("#include <linux/setbits.h>\n", line):
+ print("INFO: header already here")
+ sys.exit(0)
+ if re.search("^#include <", line):
+ found_global_headers = True
+ if re.search("^#include \"", line):
+ found_local_headers = True
+ fp.close()
+
+if not found_global_headers and not found_local_headers:
+ print("No header included do it at hand")
+ sys.exit(1)
+
+if found_global_headers:
+ done = False
+ inheader = False
+ with open("%s.new" % sys.argv[1], 'w') as fw:
+ with open(sys.argv[1], 'r') as fp:
+ for line in fp:
+ if re.search("^#include <linux/", line):
+ inheader = True
+ if (not done and line[16] >= "s" and line[17] >= "e" and line[18] >= "t" and line[19] >= 'b'):
+ done = True
+ fw.write("#include <linux/setbits.h>\n")
+ if not done and not re.search("^#include <linux/", line) and inheader:
+ done = True
+ fw.write("#include <linux/setbits.h>\n")
+ fw.write(line)
+ fw.close()
+ fp.close()
+else:
+ done = False
+ with open("%s.new" % sys.argv[1], 'w') as fw:
+ with open(sys.argv[1], 'r') as fp:
+ for line in fp:
+ if not done and re.search("^#include \"", line):
+ fw.write("#include <linux/setbits.h>\n")
+ done = True
+ fw.write(line)
+ fw.close()
+ fp.close()
+
+shutil.move("%s.new" % sys.argv[1], sys.argv[1])
+print("%s done" % sys.argv[1])
diff --git a/scripts/coccinelle/misc/setbits32.cocci b/scripts/coccinelle/misc/setbits32.cocci
new file mode 100644
index 000000000000..71400cac6830
--- /dev/null
+++ b/scripts/coccinelle/misc/setbits32.cocci
@@ -0,0 +1,487 @@
+// SPDX-License-Identifier: GPL-2.0
+// Confidence: High
+// Copyright: (c) 2018 Corentin LABBE
+
+virtual patch
+
+@p_clrsetbits_le32_l4@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr &= ~clear;
+- rr |= set;
+- writel(rr, addr);
++ clrsetbits_le32(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrsetbits_le32_l4@
+p1 << p_clrsetbits_le32_l4.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrsetbits_le32_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr &= ~clear | set;
+- writel(rr, addr);
++ clrsetbits_le32(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrsetbits_le32_l3@
+p1 << p_clrsetbits_le32_l3.p;
+@@
+list.append(p1[0].file)
+
+
+
+@p_clrsetbits_oneliner@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel@p(readl(addr) & ~mask | set, addr);
++ clrsetbits_le32(addr, mask, set);
+
+@script:python depends on p_clrsetbits_oneliner@
+p1 << p_clrsetbits_oneliner.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrsetbits_oneliner_b@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel@p((readl(addr) & ~mask) | set, addr);
++ clrsetbits_le32(addr, mask, set);
+
+@script:python depends on p_clrsetbits_oneliner_b@
+p1 << p_clrsetbits_oneliner_b.p;
+@@
+list.append(p1[0].file)
+
+
+
+// setclrbits ==========================
+
+
+
+@p_setclrbits_le32_l4@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr |= set;
+- rr &= ~clear;
+- writel(rr, addr);
++ setclrbits_le32(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setclrbits_le32_l4@
+p1 << p_setclrbits_le32_l4.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setclrbits_le32_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr |= set & ~clear;
+- writel(rr, addr);
++ setclrbits_le32(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setclrbits_le32_l3@
+p1 << p_setclrbits_le32_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setclrbits_oneliner@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel@p(readl(addr) | set & ~mask, addr);
++ setclrbits_le32(addr, mask, set);
+
+@script:python depends on p_setclrbits_oneliner@
+p1 << p_setclrbits_oneliner.p;
+@@
+list.append(p1[0].file)
+
+@p_setclrbits_oneliner_b@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel@p((readl(addr) | set) & ~mask, addr);
++ setclrbits_le32(addr, mask, set);
+
+@script:python depends on p_setclrbits_oneliner_b@
+p1 << p_setclrbits_oneliner_b.p;
+@@
+list.append(p1[0].file)
+
+
+// clr bits ===============================================
+
+@p_clrbits_le32_l3@
+local idexpression rr;
+expression addr;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr &= ~clear;
+- writel(rr, addr);
++ clrbits_le32(addr, clear);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le32_l3@
+p1 << p_clrbits_le32_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le32_l2_a@
+local idexpression rr;
+expression addr;
+expression mask;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- writel(rr & ~mask, addr);
++ clrbits_le32(addr, mask);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le32_l2_a@
+p1 << p_clrbits_le32_l2_a.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le32_l2_b@
+local idexpression rr;
+expression addr;
+expression mask;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr) & ~mask;
+- writel(rr, addr);
++ clrbits_le32(addr, mask);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le32_l2_b@
+p1 << p_clrbits_le32_l2_b.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le32_oneliner@
+expression addr;
+expression mask;
+position p;
+@@
+- writel@p(readl(addr) & ~mask, addr);
++ clrbits_le32(addr, mask);
+
+@script:python depends on p_clrbits_le32_oneliner@
+p1 << p_clrbits_le32_oneliner.p;
+@@
+list.append(p1[0].file)
+
+
+
+
+
+
+
+// set bits ======================================
+
+@p_setbits_le32_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr |= set;
+- writel(rr, addr);
++ setbits_le32(addr, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setbits_le32_l3@
+p1 << p_setbits_le32_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setbits_le32_l4@
+local idexpression rr;
+expression addr;
+expression set1;
+expression set2;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr |= set1;
+- rr |= set2;
+- writel(rr, addr);
++ setbits_le32(addr, set1 | set2);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setbits_le32_l4@
+p1 << p_setbits_le32_l4.p;
+@@
+list.append(p1[0].file)
+
+
+
+
+
+@ppsetbits_le32@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readl(addr);
+- rr |= set;
+- writel(rr, addr);
++ setbits_le32(addr, set);
+ ... when != rr
+? rr = e
+
+
+@p_setbits_le32_m2@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readl(addr);
+- writel(rr | set, addr);
++ setbits_le32(addr, set);
+ ... when != rr
+? rr = e
+
+@p_setbits_le32_l2@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readl(addr) | set;
+- writel(rr, addr);
++ setbits_le32(addr, set);
+ ... when != rr
+? rr = e
+
+
+@p_setbits_oneliner@
+expression addr;
+expression set;
+@@
+- writel(readl(addr) | set, addr);
++ setbits_le32(addr, set);
+
+
+
+
+
+// misc pattern ======================================
+
+
+@p_if_set_clr@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+ if (...)
+- rr |= set;
++ setbits_le32(addr, set);
+ else
+- rr &= ~clear;
++ clrbits_le32(addr, clear);
+- writel(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_set_clr@
+p1 << p_if_set_clr.p;
+@@
+//import subprocess
+list.append(p1[0].file)
+//file = p1[0].file
+//print("Add setbits header in %s" % file)
+//subprocess.call(["./add_header.py", file])
+
+
+@p_if_clr_set@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+ if (...)
+- rr &= ~clear;
++ clrbits_le32(addr, clear);
+ else
+- rr |= set;
++ setbits_le32(addr, set);
+- writel(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set@
+p1 << p_if_clr_set.p;
+@@
+list.append(p1[0].file)
+
+
+
+@p_if_clr_set_b@
+local idexpression rr;
+expression addr;
+expression set1;
+expression set2;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr &= ~clear;
+ if (...)
+- rr |= set1;
++ clrsetbits_le32(addr, clear, set1);
+ else
+- rr |= set2;
++ clrsetbits_le32(addr, clear, set2);
+- writel(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set_b@
+p1 << p_if_clr_set_b.p;
+@@
+list.append(p1[0].file)
+
+
+@p_if_clr_set_c@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl(addr);
+- rr &= ~clear;
+ if (...)
+- rr |= set;
++ clrsetbits_le32(addr, clear, set);
++ else
++ setbits_le32(addr, set);
+- writel(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set_c@
+p1 << p_if_clr_set_c.p;
+@@
+list.append(p1[0].file)
+
+
+
+// to check decon_set_bits
+//@p_setmask_a@
+//local idexpression rr;
+//expression addr;
+//expression set;
+//expression mask;
+//@@
+//- rr = (set & mask) | (readl(addr) & ~mask);
+//- writel(rr, addr);
+//+ setmask_le32(addr, set, mask);
+
+
+
+
+
+@initialize:python@
+@@
+list = []
+
+//@finalize:python depends on addr@
+@finalize:python@
+@@
+import subprocess
+for file in list:
+ print("Add setbits header in %s" % file)
+ subprocess.call(["./scripts/add_new_include_in_source.py", file])
+
diff --git a/scripts/coccinelle/misc/setbits32_relaxed.cocci b/scripts/coccinelle/misc/setbits32_relaxed.cocci
new file mode 100644
index 000000000000..edf8c39e939e
--- /dev/null
+++ b/scripts/coccinelle/misc/setbits32_relaxed.cocci
@@ -0,0 +1,487 @@
+// SPDX-License-Identifier: GPL-2.0
+// Confidence: High
+// Copyright: (c) 2018 Corentin LABBE
+
+virtual patch
+
+@p_clrsetbits_le32_relaxed_l4@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr &= ~clear;
+- rr |= set;
+- writel_relaxed(rr, addr);
++ clrsetbits_le32_relaxed(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrsetbits_le32_relaxed_l4@
+p1 << p_clrsetbits_le32_relaxed_l4.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrsetbits_le32_relaxed_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr &= ~clear | set;
+- writel_relaxed(rr, addr);
++ clrsetbits_le32_relaxed(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrsetbits_le32_relaxed_l3@
+p1 << p_clrsetbits_le32_relaxed_l3.p;
+@@
+list.append(p1[0].file)
+
+
+
+@p_clrsetbits_oneliner@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel_relaxed@p(readl_relaxed(addr) & ~mask | set, addr);
++ clrsetbits_le32_relaxed(addr, mask, set);
+
+@script:python depends on p_clrsetbits_oneliner@
+p1 << p_clrsetbits_oneliner.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrsetbits_oneliner_b@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel_relaxed@p((readl_relaxed(addr) & ~mask) | set, addr);
++ clrsetbits_le32_relaxed(addr, mask, set);
+
+@script:python depends on p_clrsetbits_oneliner_b@
+p1 << p_clrsetbits_oneliner_b.p;
+@@
+list.append(p1[0].file)
+
+
+
+// setclrbits ==========================
+
+
+
+@p_setclrbits_le32_relaxed_l4@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr |= set;
+- rr &= ~clear;
+- writel_relaxed(rr, addr);
++ setclrbits_le32_relaxed(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setclrbits_le32_relaxed_l4@
+p1 << p_setclrbits_le32_relaxed_l4.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setclrbits_le32_relaxed_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr |= set & ~clear;
+- writel_relaxed(rr, addr);
++ setclrbits_le32_relaxed(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setclrbits_le32_relaxed_l3@
+p1 << p_setclrbits_le32_relaxed_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setclrbits_oneliner@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel_relaxed@p(readl_relaxed(addr) | set & ~mask, addr);
++ setclrbits_le32_relaxed(addr, mask, set);
+
+@script:python depends on p_setclrbits_oneliner@
+p1 << p_setclrbits_oneliner.p;
+@@
+list.append(p1[0].file)
+
+@p_setclrbits_oneliner_b@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writel_relaxed@p((readl_relaxed(addr) | set) & ~mask, addr);
++ setclrbits_le32_relaxed(addr, mask, set);
+
+@script:python depends on p_setclrbits_oneliner_b@
+p1 << p_setclrbits_oneliner_b.p;
+@@
+list.append(p1[0].file)
+
+
+// clr bits ===============================================
+
+@p_clrbits_le32_relaxed_l3@
+local idexpression rr;
+expression addr;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr &= ~clear;
+- writel_relaxed(rr, addr);
++ clrbits_le32_relaxed(addr, clear);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le32_relaxed_l3@
+p1 << p_clrbits_le32_relaxed_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le32_relaxed_l2_a@
+local idexpression rr;
+expression addr;
+expression mask;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- writel_relaxed(rr & ~mask, addr);
++ clrbits_le32_relaxed(addr, mask);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le32_relaxed_l2_a@
+p1 << p_clrbits_le32_relaxed_l2_a.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le32_relaxed_l2_b@
+local idexpression rr;
+expression addr;
+expression mask;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr) & ~mask;
+- writel_relaxed(rr, addr);
++ clrbits_le32_relaxed(addr, mask);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le32_relaxed_l2_b@
+p1 << p_clrbits_le32_relaxed_l2_b.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le32_relaxed_oneliner@
+expression addr;
+expression mask;
+position p;
+@@
+- writel_relaxed@p(readl_relaxed(addr) & ~mask, addr);
++ clrbits_le32_relaxed(addr, mask);
+
+@script:python depends on p_clrbits_le32_relaxed_oneliner@
+p1 << p_clrbits_le32_relaxed_oneliner.p;
+@@
+list.append(p1[0].file)
+
+
+
+
+
+
+
+// set bits ======================================
+
+@p_setbits_le32_relaxed_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr |= set;
+- writel_relaxed(rr, addr);
++ setbits_le32_relaxed(addr, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setbits_le32_relaxed_l3@
+p1 << p_setbits_le32_relaxed_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setbits_le32_relaxed_l4@
+local idexpression rr;
+expression addr;
+expression set1;
+expression set2;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr |= set1;
+- rr |= set2;
+- writel_relaxed(rr, addr);
++ setbits_le32_relaxed(addr, set1 | set2);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setbits_le32_relaxed_l4@
+p1 << p_setbits_le32_relaxed_l4.p;
+@@
+list.append(p1[0].file)
+
+
+
+
+
+@ppsetbits_le32_relaxed@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readl_relaxed(addr);
+- rr |= set;
+- writel_relaxed(rr, addr);
++ setbits_le32_relaxed(addr, set);
+ ... when != rr
+? rr = e
+
+
+@p_setbits_le32_relaxed_m2@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readl_relaxed(addr);
+- writel_relaxed(rr | set, addr);
++ setbits_le32_relaxed(addr, set);
+ ... when != rr
+? rr = e
+
+@p_setbits_le32_relaxed_l2@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readl_relaxed(addr) | set;
+- writel_relaxed(rr, addr);
++ setbits_le32_relaxed(addr, set);
+ ... when != rr
+? rr = e
+
+
+@p_setbits_oneliner@
+expression addr;
+expression set;
+@@
+- writel_relaxed(readl_relaxed(addr) | set, addr);
++ setbits_le32_relaxed(addr, set);
+
+
+
+
+
+// misc pattern ======================================
+
+
+@p_if_set_clr@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+ if (...)
+- rr |= set;
++ setbits_le32_relaxed(addr, set);
+ else
+- rr &= ~clear;
++ clrbits_le32_relaxed(addr, clear);
+- writel_relaxed(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_set_clr@
+p1 << p_if_set_clr.p;
+@@
+//import subprocess
+list.append(p1[0].file)
+//file = p1[0].file
+//print("Add setbits header in %s" % file)
+//subprocess.call(["./add_header.py", file])
+
+
+@p_if_clr_set@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+ if (...)
+- rr &= ~clear;
++ clrbits_le32_relaxed(addr, clear);
+ else
+- rr |= set;
++ setbits_le32_relaxed(addr, set);
+- writel_relaxed(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set@
+p1 << p_if_clr_set.p;
+@@
+list.append(p1[0].file)
+
+
+
+@p_if_clr_set_b@
+local idexpression rr;
+expression addr;
+expression set1;
+expression set2;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr &= ~clear;
+ if (...)
+- rr |= set1;
++ clrsetbits_le32_relaxed(addr, clear, set1);
+ else
+- rr |= set2;
++ clrsetbits_le32_relaxed(addr, clear, set2);
+- writel_relaxed(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set_b@
+p1 << p_if_clr_set_b.p;
+@@
+list.append(p1[0].file)
+
+
+@p_if_clr_set_c@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readl_relaxed(addr);
+- rr &= ~clear;
+ if (...)
+- rr |= set;
++ clrsetbits_le32_relaxed(addr, clear, set);
++ else
++ setbits_le32_relaxed(addr, set);
+- writel_relaxed(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set_c@
+p1 << p_if_clr_set_c.p;
+@@
+list.append(p1[0].file)
+
+
+
+// to check decon_set_bits
+//@p_setmask_a@
+//local idexpression rr;
+//expression addr;
+//expression set;
+//expression mask;
+//@@
+//- rr = (set & mask) | (readl_relaxed(addr) & ~mask);
+//- writel_relaxed(rr, addr);
+//+ setmask_le32(addr, set, mask);
+
+
+
+
+
+@initialize:python@
+@@
+list = []
+
+//@finalize:python depends on addr@
+@finalize:python@
+@@
+import subprocess
+for file in list:
+ print("Add setbits header in %s" % file)
+ subprocess.call(["./scripts/add_new_include_in_source.py", file])
+
diff --git a/scripts/coccinelle/misc/setbits64.cocci b/scripts/coccinelle/misc/setbits64.cocci
new file mode 100644
index 000000000000..00df21005b18
--- /dev/null
+++ b/scripts/coccinelle/misc/setbits64.cocci
@@ -0,0 +1,487 @@
+// SPDX-License-Identifier: GPL-2.0
+// Confidence: High
+// Copyright: (c) 2018 Corentin LABBE
+
+virtual patch
+
+@p_clrsetbits_le64_l4@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr &= ~clear;
+- rr |= set;
+- writeq(rr, addr);
++ clrsetbits_le64(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrsetbits_le64_l4@
+p1 << p_clrsetbits_le64_l4.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrsetbits_le64_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr &= ~clear | set;
+- writeq(rr, addr);
++ clrsetbits_le64(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrsetbits_le64_l3@
+p1 << p_clrsetbits_le64_l3.p;
+@@
+list.append(p1[0].file)
+
+
+
+@p_clrsetbits_oneliner@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writeq@p(readq(addr) & ~mask | set, addr);
++ clrsetbits_le64(addr, mask, set);
+
+@script:python depends on p_clrsetbits_oneliner@
+p1 << p_clrsetbits_oneliner.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrsetbits_oneliner_b@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writeq@p((readq(addr) & ~mask) | set, addr);
++ clrsetbits_le64(addr, mask, set);
+
+@script:python depends on p_clrsetbits_oneliner_b@
+p1 << p_clrsetbits_oneliner_b.p;
+@@
+list.append(p1[0].file)
+
+
+
+// setclrbits ==========================
+
+
+
+@p_setclrbits_le64_l4@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr |= set;
+- rr &= ~clear;
+- writeq(rr, addr);
++ setclrbits_le64(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setclrbits_le64_l4@
+p1 << p_setclrbits_le64_l4.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setclrbits_le64_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr |= set & ~clear;
+- writeq(rr, addr);
++ setclrbits_le64(addr, clear, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setclrbits_le64_l3@
+p1 << p_setclrbits_le64_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setclrbits_oneliner@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writeq@p(readq(addr) | set & ~mask, addr);
++ setclrbits_le64(addr, mask, set);
+
+@script:python depends on p_setclrbits_oneliner@
+p1 << p_setclrbits_oneliner.p;
+@@
+list.append(p1[0].file)
+
+@p_setclrbits_oneliner_b@
+expression addr;
+expression set;
+expression mask;
+position p;
+@@
+- writeq@p((readq(addr) | set) & ~mask, addr);
++ setclrbits_le64(addr, mask, set);
+
+@script:python depends on p_setclrbits_oneliner_b@
+p1 << p_setclrbits_oneliner_b.p;
+@@
+list.append(p1[0].file)
+
+
+// clr bits ===============================================
+
+@p_clrbits_le64_l3@
+local idexpression rr;
+expression addr;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr &= ~clear;
+- writeq(rr, addr);
++ clrbits_le64(addr, clear);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le64_l3@
+p1 << p_clrbits_le64_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le64_l2_a@
+local idexpression rr;
+expression addr;
+expression mask;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- writeq(rr & ~mask, addr);
++ clrbits_le64(addr, mask);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le64_l2_a@
+p1 << p_clrbits_le64_l2_a.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le64_l2_b@
+local idexpression rr;
+expression addr;
+expression mask;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr) & ~mask;
+- writeq(rr, addr);
++ clrbits_le64(addr, mask);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_clrbits_le64_l2_b@
+p1 << p_clrbits_le64_l2_b.p;
+@@
+list.append(p1[0].file)
+
+
+@p_clrbits_le64_oneliner@
+expression addr;
+expression mask;
+position p;
+@@
+- writeq@p(readq(addr) & ~mask, addr);
++ clrbits_le64(addr, mask);
+
+@script:python depends on p_clrbits_le64_oneliner@
+p1 << p_clrbits_le64_oneliner.p;
+@@
+list.append(p1[0].file)
+
+
+
+
+
+
+
+// set bits ======================================
+
+@p_setbits_le64_l3@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr |= set;
+- writeq(rr, addr);
++ setbits_le64(addr, set);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setbits_le64_l3@
+p1 << p_setbits_le64_l3.p;
+@@
+list.append(p1[0].file)
+
+
+@p_setbits_le64_l4@
+local idexpression rr;
+expression addr;
+expression set1;
+expression set2;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr |= set1;
+- rr |= set2;
+- writeq(rr, addr);
++ setbits_le64(addr, set1 | set2);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_setbits_le64_l4@
+p1 << p_setbits_le64_l4.p;
+@@
+list.append(p1[0].file)
+
+
+
+
+
+@ppsetbits_le64@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readq(addr);
+- rr |= set;
+- writeq(rr, addr);
++ setbits_le64(addr, set);
+ ... when != rr
+? rr = e
+
+
+@p_setbits_le64_m2@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readq(addr);
+- writeq(rr | set, addr);
++ setbits_le64(addr, set);
+ ... when != rr
+? rr = e
+
+@p_setbits_le64_l2@
+local idexpression rr;
+expression addr;
+expression set;
+expression e;
+@@
+
+- rr = readq(addr) | set;
+- writeq(rr, addr);
++ setbits_le64(addr, set);
+ ... when != rr
+? rr = e
+
+
+@p_setbits_oneliner@
+expression addr;
+expression set;
+@@
+- writeq(readq(addr) | set, addr);
++ setbits_le64(addr, set);
+
+
+
+
+
+// misc pattern ======================================
+
+
+@p_if_set_clr@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+ if (...)
+- rr |= set;
++ setbits_le64(addr, set);
+ else
+- rr &= ~clear;
++ clrbits_le64(addr, clear);
+- writeq(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_set_clr@
+p1 << p_if_set_clr.p;
+@@
+//import subprocess
+list.append(p1[0].file)
+//file = p1[0].file
+//print("Add setbits header in %s" % file)
+//subprocess.call(["./add_header.py", file])
+
+
+@p_if_clr_set@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+ if (...)
+- rr &= ~clear;
++ clrbits_le64(addr, clear);
+ else
+- rr |= set;
++ setbits_le64(addr, set);
+- writeq(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set@
+p1 << p_if_clr_set.p;
+@@
+list.append(p1[0].file)
+
+
+
+@p_if_clr_set_b@
+local idexpression rr;
+expression addr;
+expression set1;
+expression set2;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr &= ~clear;
+ if (...)
+- rr |= set1;
++ clrsetbits_le64(addr, clear, set1);
+ else
+- rr |= set2;
++ clrsetbits_le64(addr, clear, set2);
+- writeq(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set_b@
+p1 << p_if_clr_set_b.p;
+@@
+list.append(p1[0].file)
+
+
+@p_if_clr_set_c@
+local idexpression rr;
+expression addr;
+expression set;
+expression clear;
+expression e;
+position p;
+@@
+
+- rr@p = readq(addr);
+- rr &= ~clear;
+ if (...)
+- rr |= set;
++ clrsetbits_le64(addr, clear, set);
++ else
++ setbits_le64(addr, set);
+- writeq(rr, addr);
+ ... when != rr
+? rr = e
+
+@script:python depends on p_if_clr_set_c@
+p1 << p_if_clr_set_c.p;
+@@
+list.append(p1[0].file)
+
+
+
+// to check decon_set_bits
+//@p_setmask_a@
+//local idexpression rr;
+//expression addr;
+//expression set;
+//expression mask;
+//@@
+//- rr = (set & mask) | (readq(addr) & ~mask);
+//- writeq(rr, addr);
+//+ setmask_le64(addr, set, mask);
+
+
+
+
+
+@initialize:python@
+@@
+list = []
+
+//@finalize:python depends on addr@
+@finalize:python@
+@@
+import subprocess
+for file in list:
+ print("Add setbits header in %s" % file)
+ subprocess.call(["./scripts/add_new_include_in_source.py", file])
+
diff --git a/scripts/coccinelle/misc/setbits_dev.cocci b/scripts/coccinelle/misc/setbits_dev.cocci
new file mode 100644
index 000000000000..859bd0526fcc
--- /dev/null
+++ b/scripts/coccinelle/misc/setbits_dev.cocci
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+// Confidence: High
+// Copyright: (c) 2018 Corentin LABBE
+
+virtual patch
+
+// ========================================================================
+// driver specific changes
+// to be removed after conversion
+
+
+// mtk_hdmi_phy_mask
+@p_setmask_b@
+local idexpression rr;
+expression addr;
+expression set;
+expression mask;
+@@
+- rr = readl(addr);
+- rr = (rr & ~mask) | (set & mask);
+- writel(rr, addr);
++ setmask_le32(addr, set, mask);
+
+@p_setmask_c@
+local idexpression rr;
+expression addr;
+expression set;
+expression mask;
+@@
+- rr = readl(addr);
+- rr = (set & mask) | (rr & ~mask);
+- writel(rr, addr);
++ setmask_le32(addr, set, mask);
+
+
+@p_net_meson_clean@
+@@
+- meson8b_dwmac_mask_bits(...) {
+- ...
+- }
+
+@p_net_meson@
+expression dwmac;
+expression addr;
+expression mask;
+expression value;
+@@
+
+- meson8b_dwmac_mask_bits(dwmac, addr, mask, value);
++ clrsetbits_le32(dwmac->regs + addr, mask, value);
+
+// meson DRM
+@p_meson_drm_writel@
+expression addr;
+expression set;
+expression mask;
+@@
+- writel_bits_relaxed(mask, set, addr);
++ clrsetbits_le32_relaxed(addr, mask, set);
+
+@p_mtu3_setbits@
+expression base;
+expression offset;
+expression value;
+@@
+
+- mtu3_setbits(base, offset, value);
++ setbits_le32(base + offset, value);
+
+@p_mtu3_clrbits@
+expression base;
+expression offset;
+expression mask;
+@@
+
+- mtu3_clrbits(base, offset, mask);
++ clrbits_le32(base + offset, mask);
+
+//
+@p_fimc_clean_set@
+@@
+- static void fimc_set_bits(...) {
+- ...
+- }
+
+@p_fimc_clean_clrt@
+@@
+- static void fimc_clear_bits(...) {
+- ...
+- }
+
+@p_fimc_setbits@
+expression fimc;
+expression offset;
+expression value;
+@@
+
+- fimc_set_bits(fimc, offset, value);
++ setbits_le32(fimc->regs + offset, value);
+
+@p_fimc_clrbits@
+expression fimc;
+expression offset;
+expression mask;
+@@
+
+- fimc_clear_bits(fimc, offset, mask);
++ clrbits_le32(fimc->regs + offset, mask);
+
+//
+@p_sif_clean_clr@
+@@
+- static void sif_clr_bit(...) {
+- ...
+- }
+
+@p_sif_clean_set@
+@@
+- static void sif_set_bit(...) {
+- ...
+- }
+
+@p_sif_setbits@
+expression sif;
+expression offset;
+expression value;
+@@
+
+- sif_set_bit(sif, offset, value);
++ setbits_le32(sif->regs + offset, value);
+
+@p_sif_clrbits@
+expression sif;
+expression offset;
+expression mask;
+@@
+
+- sif_clr_bit(sif, offset, mask);
++ clrbits_le32(sif->regs + offset, mask);
+
+// mediatek
+@p_mtk_clean_clr@
+@@
+- static void mtk_cec_clear_bits(...) {
+- ...
+- }
+
+@p_mtk_clean_set@
+@@
+- static void mtk_cec_set_bits(...) {
+- ...
+- }
+
+@p_mtk_setbits@
+expression mtk;
+expression offset;
+expression value;
+@@
+
+- mtk_cec_set_bits(mtk, offset, value);
++ setbits_le32(mtk->regs + offset, value);
+
+@p_mtk_clrbits@
+expression mtk;
+expression offset;
+expression mask;
+@@
+
+- mtk_cec_clear_bits(mtk, offset, mask);
++ clrbits_le32(mtk->regs + offset, mask);
+
+// mediatek HDMI
+@p_mtk_hdmi_clean_set@
+@@
+- static void mtk_hdmi_set_bits(...) {
+- ...
+- }
+
+@p_mtk_hdmi_clean_clr@
+@@
+- static void mtk_hdmi_clear_bits(...) {
+- ...
+- }
+
+@p_mtk_hdmi_setbits@
+expression mtk;
+expression offset;
+expression value;
+@@
+
+- mtk_hdmi_set_bits(mtk, offset, value);
++ setbits_le32(mtk->regs + offset, value);
+
+@p_mtk_hdmi_clrbits@
+expression mtk;
+expression offset;
+expression mask;
+@@
+
+- mtk_hdmi_clear_bits(mtk, offset, mask);
++ clrbits_le32(mtk->regs + offset, mask);
+
+// mediatek HDMI
+@p_mtk_hdmi_phy_clean_set@
+@@
+- static void mtk_hdmi_phy_set_bits(...) {
+- ...
+- }
+
+@p_mtk_hdmi_phy_clean_clr@
+@@
+- static void mtk_hdmi_phy_clear_bits(...) {
+- ...
+- }
+
+@p_mtk_hdmi_phy_setbits@
+expression mtk;
+expression offset;
+expression value;
+@@
+
+- mtk_hdmi_phy_set_bits(mtk, offset, value);
++ setbits_le32(mtk->regs + offset, value);
+
+@p_mtk_hdmi_phy_clrbits@
+expression mtk;
+expression offset;
+expression mask;
+@@
+
+- mtk_hdmi_phy_clear_bits(mtk, offset, mask);
++ clrbits_le32(mtk->regs + offset, mask);
+
+
+
--
2.16.4
^ permalink raw reply related
* [PATCH v2 4/7] ata: ahci_sunxi: use xxxsetbits32 functions
From: Corentin Labbe @ 2018-09-24 19:04 UTC (permalink / raw)
To: Gilles.Muller, Julia.Lawall, agust, airlied, alexandre.torgue,
alistair, benh, carlo, davem, galak, joabreu, khilman,
maxime.ripard, michal.lkml, mpe, mporter, narmstrong,
nicolas.palix, oss, paulus, peppe.cavallaro, tj, vitb, wens
Cc: cocci, dri-devel, linux-amlogic, linux-arm-kernel, linux-ide,
linux-kernel, linuxppc-dev, netdev, Corentin Labbe
In-Reply-To: <1537815856-31728-1-git-send-email-clabbe@baylibre.com>
This patch converts ahci_sunxi to use xxxsetbits32 functions
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
drivers/ata/ahci_sunxi.c | 51 ++++++++++++------------------------------------
1 file changed, 12 insertions(+), 39 deletions(-)
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
index 911710643305..5b285a6dff60 100644
--- a/drivers/ata/ahci_sunxi.c
+++ b/drivers/ata/ahci_sunxi.c
@@ -25,6 +25,7 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/setbits.h>
#include "ahci.h"
#define DRV_NAME "ahci-sunxi"
@@ -58,34 +59,6 @@ MODULE_PARM_DESC(enable_pmp,
#define AHCI_P0PHYCR 0x0178
#define AHCI_P0PHYSR 0x017c
-static void sunxi_clrbits(void __iomem *reg, u32 clr_val)
-{
- u32 reg_val;
-
- reg_val = readl(reg);
- reg_val &= ~(clr_val);
- writel(reg_val, reg);
-}
-
-static void sunxi_setbits(void __iomem *reg, u32 set_val)
-{
- u32 reg_val;
-
- reg_val = readl(reg);
- reg_val |= set_val;
- writel(reg_val, reg);
-}
-
-static void sunxi_clrsetbits(void __iomem *reg, u32 clr_val, u32 set_val)
-{
- u32 reg_val;
-
- reg_val = readl(reg);
- reg_val &= ~(clr_val);
- reg_val |= set_val;
- writel(reg_val, reg);
-}
-
static u32 sunxi_getbits(void __iomem *reg, u8 mask, u8 shift)
{
return (readl(reg) >> shift) & mask;
@@ -100,22 +73,22 @@ static int ahci_sunxi_phy_init(struct device *dev, void __iomem *reg_base)
writel(0, reg_base + AHCI_RWCR);
msleep(5);
- sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19));
- sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+ setbits_le32(reg_base + AHCI_PHYCS1R, BIT(19));
+ clrsetbits_le32(reg_base + AHCI_PHYCS0R,
(0x7 << 24),
(0x5 << 24) | BIT(23) | BIT(18));
- sunxi_clrsetbits(reg_base + AHCI_PHYCS1R,
+ clrsetbits_le32(reg_base + AHCI_PHYCS1R,
(0x3 << 16) | (0x1f << 8) | (0x3 << 6),
(0x2 << 16) | (0x6 << 8) | (0x2 << 6));
- sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15));
- sunxi_clrbits(reg_base + AHCI_PHYCS1R, BIT(19));
- sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+ setbits_le32(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15));
+ clrbits_le32(reg_base + AHCI_PHYCS1R, BIT(19));
+ clrsetbits_le32(reg_base + AHCI_PHYCS0R,
(0x7 << 20), (0x3 << 20));
- sunxi_clrsetbits(reg_base + AHCI_PHYCS2R,
+ clrsetbits_le32(reg_base + AHCI_PHYCS2R,
(0x1f << 5), (0x19 << 5));
msleep(5);
- sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19));
+ setbits_le32(reg_base + AHCI_PHYCS0R, (0x1 << 19));
timeout = 250; /* Power up takes aprox 50 us */
do {
@@ -130,7 +103,7 @@ static int ahci_sunxi_phy_init(struct device *dev, void __iomem *reg_base)
udelay(1);
} while (1);
- sunxi_setbits(reg_base + AHCI_PHYCS2R, (0x1 << 24));
+ setbits_le32(reg_base + AHCI_PHYCS2R, (0x1 << 24));
timeout = 100; /* Calibration takes aprox 10 us */
do {
@@ -158,10 +131,10 @@ static void ahci_sunxi_start_engine(struct ata_port *ap)
struct ahci_host_priv *hpriv = ap->host->private_data;
/* Setup DMA before DMA start */
- sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400);
+ clrsetbits_le32(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400);
/* Start DMA */
- sunxi_setbits(port_mmio + PORT_CMD, PORT_CMD_START);
+ setbits_le32(port_mmio + PORT_CMD, PORT_CMD_START);
}
static const struct ata_port_info ahci_sunxi_port_info = {
--
2.16.4
^ permalink raw reply related
* [PATCH v2 1/7] powerpc: rename setbits32/clrbits32 to setbits32_be/clrbits32_be
From: Corentin Labbe @ 2018-09-24 19:04 UTC (permalink / raw)
To: Gilles.Muller, Julia.Lawall, agust, airlied, alexandre.torgue,
alistair, benh, carlo, davem, galak, joabreu, khilman,
maxime.ripard, michal.lkml, mpe, mporter, narmstrong,
nicolas.palix, oss, paulus, peppe.cavallaro, tj, vitb, wens
Cc: cocci, dri-devel, linux-amlogic, linux-arm-kernel, linux-ide,
linux-kernel, linuxppc-dev, netdev, Corentin Labbe
In-Reply-To: <1537815856-31728-1-git-send-email-clabbe@baylibre.com>
Since setbits32/clrbits32 work on be32, it's better to remove ambiguity on
the used data type.
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
arch/powerpc/include/asm/fsl_lbc.h | 2 +-
arch/powerpc/include/asm/io.h | 5 +-
arch/powerpc/platforms/44x/canyonlands.c | 4 +-
arch/powerpc/platforms/4xx/gpio.c | 28 ++++-----
arch/powerpc/platforms/512x/pdm360ng.c | 6 +-
arch/powerpc/platforms/52xx/mpc52xx_common.c | 6 +-
arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 10 ++--
arch/powerpc/platforms/82xx/ep8248e.c | 2 +-
arch/powerpc/platforms/82xx/km82xx.c | 6 +-
arch/powerpc/platforms/82xx/mpc8272_ads.c | 10 ++--
arch/powerpc/platforms/82xx/pq2.c | 2 +-
arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 4 +-
arch/powerpc/platforms/82xx/pq2fads.c | 10 ++--
arch/powerpc/platforms/83xx/km83xx.c | 6 +-
arch/powerpc/platforms/83xx/mpc836x_mds.c | 2 +-
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 2 +-
arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c | 4 +-
arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 2 +-
arch/powerpc/platforms/85xx/p1022_ds.c | 4 +-
arch/powerpc/platforms/85xx/p1022_rdk.c | 4 +-
arch/powerpc/platforms/85xx/t1042rdb_diu.c | 4 +-
arch/powerpc/platforms/85xx/twr_p102x.c | 2 +-
arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 4 +-
arch/powerpc/platforms/8xx/adder875.c | 2 +-
arch/powerpc/platforms/8xx/m8xx_setup.c | 4 +-
arch/powerpc/platforms/8xx/mpc86xads_setup.c | 4 +-
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 28 ++++-----
arch/powerpc/platforms/embedded6xx/flipper-pic.c | 6 +-
arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 8 +--
arch/powerpc/platforms/embedded6xx/wii.c | 10 ++--
arch/powerpc/sysdev/cpm1.c | 26 ++++-----
arch/powerpc/sysdev/cpm2.c | 16 ++---
arch/powerpc/sysdev/cpm_common.c | 4 +-
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 8 +--
arch/powerpc/sysdev/fsl_lbc.c | 2 +-
arch/powerpc/sysdev/fsl_pci.c | 8 +--
arch/powerpc/sysdev/fsl_pmc.c | 2 +-
arch/powerpc/sysdev/fsl_rcpm.c | 74 ++++++++++++------------
arch/powerpc/sysdev/fsl_rio.c | 4 +-
arch/powerpc/sysdev/fsl_rmu.c | 8 +--
arch/powerpc/sysdev/mpic_timer.c | 12 ++--
41 files changed, 178 insertions(+), 177 deletions(-)
diff --git a/arch/powerpc/include/asm/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h
index c7240a024b96..4d6a56b48a28 100644
--- a/arch/powerpc/include/asm/fsl_lbc.h
+++ b/arch/powerpc/include/asm/fsl_lbc.h
@@ -276,7 +276,7 @@ static inline void fsl_upm_start_pattern(struct fsl_upm *upm, u8 pat_offset)
*/
static inline void fsl_upm_end_pattern(struct fsl_upm *upm)
{
- clrbits32(upm->mxmr, MxMR_OP_RP);
+ clrbits_be32(upm->mxmr, MxMR_OP_RP);
while (in_be32(upm->mxmr) & MxMR_OP_RP)
cpu_relax();
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index e0331e754568..57486a1b9992 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -873,8 +873,8 @@ static inline void * bus_to_virt(unsigned long address)
#endif /* CONFIG_PPC32 */
/* access ports */
-#define setbits32(_addr, _v) out_be32((_addr), in_be32(_addr) | (_v))
-#define clrbits32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v))
+#define setbits_be32(_addr, _v) out_be32((_addr), in_be32(_addr) | (_v))
+#define clrbits_be32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v))
#define setbits16(_addr, _v) out_be16((_addr), in_be16(_addr) | (_v))
#define clrbits16(_addr, _v) out_be16((_addr), in_be16(_addr) & ~(_v))
@@ -904,6 +904,7 @@ static inline void * bus_to_virt(unsigned long address)
#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set)
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
+#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/44x/canyonlands.c b/arch/powerpc/platforms/44x/canyonlands.c
index 157f4ce46386..6aeb4ca64d09 100644
--- a/arch/powerpc/platforms/44x/canyonlands.c
+++ b/arch/powerpc/platforms/44x/canyonlands.c
@@ -113,8 +113,8 @@ static int __init ppc460ex_canyonlands_fixup(void)
* USB2HStop and gpio19 will be USB2DStop. For more details refer to
* table 34-7 of PPC460EX user manual.
*/
- setbits32((vaddr + GPIO0_OSRH), 0x42000000);
- setbits32((vaddr + GPIO0_TSRH), 0x42000000);
+ setbits_be32((vaddr + GPIO0_OSRH), 0x42000000);
+ setbits_be32((vaddr + GPIO0_TSRH), 0x42000000);
err_gpio:
iounmap(vaddr);
err_bcsr:
diff --git a/arch/powerpc/platforms/4xx/gpio.c b/arch/powerpc/platforms/4xx/gpio.c
index 2238e369cde4..8436da0617fd 100644
--- a/arch/powerpc/platforms/4xx/gpio.c
+++ b/arch/powerpc/platforms/4xx/gpio.c
@@ -82,9 +82,9 @@ __ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
if (val)
- setbits32(®s->or, GPIO_MASK(gpio));
+ setbits_be32(®s->or, GPIO_MASK(gpio));
else
- clrbits32(®s->or, GPIO_MASK(gpio));
+ clrbits_be32(®s->or, GPIO_MASK(gpio));
}
static void
@@ -112,18 +112,18 @@ static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
spin_lock_irqsave(&chip->lock, flags);
/* Disable open-drain function */
- clrbits32(®s->odr, GPIO_MASK(gpio));
+ clrbits_be32(®s->odr, GPIO_MASK(gpio));
/* Float the pin */
- clrbits32(®s->tcr, GPIO_MASK(gpio));
+ clrbits_be32(®s->tcr, GPIO_MASK(gpio));
/* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */
if (gpio < 16) {
- clrbits32(®s->osrl, GPIO_MASK2(gpio));
- clrbits32(®s->tsrl, GPIO_MASK2(gpio));
+ clrbits_be32(®s->osrl, GPIO_MASK2(gpio));
+ clrbits_be32(®s->tsrl, GPIO_MASK2(gpio));
} else {
- clrbits32(®s->osrh, GPIO_MASK2(gpio));
- clrbits32(®s->tsrh, GPIO_MASK2(gpio));
+ clrbits_be32(®s->osrh, GPIO_MASK2(gpio));
+ clrbits_be32(®s->tsrh, GPIO_MASK2(gpio));
}
spin_unlock_irqrestore(&chip->lock, flags);
@@ -145,18 +145,18 @@ ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
__ppc4xx_gpio_set(gc, gpio, val);
/* Disable open-drain function */
- clrbits32(®s->odr, GPIO_MASK(gpio));
+ clrbits_be32(®s->odr, GPIO_MASK(gpio));
/* Drive the pin */
- setbits32(®s->tcr, GPIO_MASK(gpio));
+ setbits_be32(®s->tcr, GPIO_MASK(gpio));
/* Bits 0-15 use TSRL, bits 16-31 use TSRH */
if (gpio < 16) {
- clrbits32(®s->osrl, GPIO_MASK2(gpio));
- clrbits32(®s->tsrl, GPIO_MASK2(gpio));
+ clrbits_be32(®s->osrl, GPIO_MASK2(gpio));
+ clrbits_be32(®s->tsrl, GPIO_MASK2(gpio));
} else {
- clrbits32(®s->osrh, GPIO_MASK2(gpio));
- clrbits32(®s->tsrh, GPIO_MASK2(gpio));
+ clrbits_be32(®s->osrh, GPIO_MASK2(gpio));
+ clrbits_be32(®s->tsrh, GPIO_MASK2(gpio));
}
spin_unlock_irqrestore(&chip->lock, flags);
diff --git a/arch/powerpc/platforms/512x/pdm360ng.c b/arch/powerpc/platforms/512x/pdm360ng.c
index dc81f05e0bce..06b95795267a 100644
--- a/arch/powerpc/platforms/512x/pdm360ng.c
+++ b/arch/powerpc/platforms/512x/pdm360ng.c
@@ -38,7 +38,7 @@ static int pdm360ng_get_pendown_state(void)
reg = in_be32(pdm360ng_gpio_base + 0xc);
if (reg & 0x40)
- setbits32(pdm360ng_gpio_base + 0xc, 0x40);
+ setbits_be32(pdm360ng_gpio_base + 0xc, 0x40);
reg = in_be32(pdm360ng_gpio_base + 0x8);
@@ -69,8 +69,8 @@ static int __init pdm360ng_penirq_init(void)
return -ENODEV;
}
out_be32(pdm360ng_gpio_base + 0xc, 0xffffffff);
- setbits32(pdm360ng_gpio_base + 0x18, 0x2000);
- setbits32(pdm360ng_gpio_base + 0x10, 0x40);
+ setbits_be32(pdm360ng_gpio_base + 0x18, 0x2000);
+ setbits_be32(pdm360ng_gpio_base + 0x10, 0x40);
return 0;
}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 565e3a83dc9e..edfe619d67bf 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -314,13 +314,13 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number)
/* enable gpio pins for output */
setbits8(&wkup_gpio->wkup_gpioe, reset);
- setbits32(&simple_gpio->simple_gpioe, sync | out);
+ setbits_be32(&simple_gpio->simple_gpioe, sync | out);
setbits8(&wkup_gpio->wkup_ddr, reset);
- setbits32(&simple_gpio->simple_ddr, sync | out);
+ setbits_be32(&simple_gpio->simple_ddr, sync | out);
/* Assert cold reset */
- clrbits32(&simple_gpio->simple_dvo, sync | out);
+ clrbits_be32(&simple_gpio->simple_dvo, sync | out);
clrbits8(&wkup_gpio->wkup_dvo, reset);
/* wait for 1 us */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 17cf249b18ee..e9f4dec06077 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -142,7 +142,7 @@ static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
unsigned long flags;
raw_spin_lock_irqsave(&gpt->lock, flags);
- setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
+ setbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
raw_spin_unlock_irqrestore(&gpt->lock, flags);
}
@@ -152,7 +152,7 @@ static void mpc52xx_gpt_irq_mask(struct irq_data *d)
unsigned long flags;
raw_spin_lock_irqsave(&gpt->lock, flags);
- clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
+ clrbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
raw_spin_unlock_irqrestore(&gpt->lock, flags);
}
@@ -308,7 +308,7 @@ static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
raw_spin_lock_irqsave(&gpt->lock, flags);
- clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
+ clrbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
raw_spin_unlock_irqrestore(&gpt->lock, flags);
return 0;
@@ -482,7 +482,7 @@ int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
return -EBUSY;
}
- clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
+ clrbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
raw_spin_unlock_irqrestore(&gpt->lock, flags);
return 0;
}
@@ -639,7 +639,7 @@ static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
unsigned long flags;
raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
- clrbits32(&gpt_wdt->regs->mode,
+ clrbits_be32(&gpt_wdt->regs->mode,
MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index 8fec050f2d5b..18626cd3db16 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -262,7 +262,7 @@ static void __init ep8248e_setup_arch(void)
/* When this is set, snooping CPM DMA from RAM causes
* machine checks. See erratum SIU18.
*/
- clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
+ clrbits_be32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
ep8248e_bcsr_node =
of_find_compatible_node(NULL, NULL, "fsl,ep8248e-bcsr");
diff --git a/arch/powerpc/platforms/82xx/km82xx.c b/arch/powerpc/platforms/82xx/km82xx.c
index 28860e40b5db..27d16d1a89f5 100644
--- a/arch/powerpc/platforms/82xx/km82xx.c
+++ b/arch/powerpc/platforms/82xx/km82xx.c
@@ -157,9 +157,9 @@ static void __init init_ioports(void)
cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
/* Force USB FULL SPEED bit to '1' */
- setbits32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 10));
+ setbits_be32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 10));
/* clear USB_SLAVE */
- clrbits32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 11));
+ clrbits_be32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 11));
}
static void __init km82xx_setup_arch(void)
@@ -172,7 +172,7 @@ static void __init km82xx_setup_arch(void)
/* When this is set, snooping CPM DMA from RAM causes
* machine checks. See erratum SIU18.
*/
- clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
+ clrbits_be32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
init_ioports();
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index d23c10a96bde..75338e9e8acc 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -164,13 +164,13 @@ static void __init mpc8272_ads_setup_arch(void)
#define BCSR3_FETHIEN2 0x10000000
#define BCSR3_FETH2_RST 0x08000000
- clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
- setbits32(&bcsr[1], BCSR1_FETH_RST);
+ clrbits_be32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
+ setbits_be32(&bcsr[1], BCSR1_FETH_RST);
- clrbits32(&bcsr[3], BCSR3_FETHIEN2);
- setbits32(&bcsr[3], BCSR3_FETH2_RST);
+ clrbits_be32(&bcsr[3], BCSR3_FETHIEN2);
+ setbits_be32(&bcsr[3], BCSR3_FETH2_RST);
- clrbits32(&bcsr[3], BCSR3_USB_nEN);
+ clrbits_be32(&bcsr[3], BCSR3_USB_nEN);
iounmap(bcsr);
diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
index c4f7029fc9ae..92f2b4a5dcc8 100644
--- a/arch/powerpc/platforms/82xx/pq2.c
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -25,7 +25,7 @@
void __noreturn pq2_restart(char *cmd)
{
local_irq_disable();
- setbits32(&cpm2_immr->im_clkrst.car_rmr, RMR_CSRE);
+ setbits_be32(&cpm2_immr->im_clkrst.car_rmr, RMR_CSRE);
/* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 8b065bdf7412..060400ec3ebb 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -47,7 +47,7 @@ static void pq2ads_pci_mask_irq(struct irq_data *d)
unsigned long flags;
raw_spin_lock_irqsave(&pci_pic_lock, flags);
- setbits32(&priv->regs->mask, 1 << irq);
+ setbits_be32(&priv->regs->mask, 1 << irq);
mb();
raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
@@ -63,7 +63,7 @@ static void pq2ads_pci_unmask_irq(struct irq_data *d)
unsigned long flags;
raw_spin_lock_irqsave(&pci_pic_lock, flags);
- clrbits32(&priv->regs->mask, 1 << irq);
+ clrbits_be32(&priv->regs->mask, 1 << irq);
raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
}
}
diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
index 6c654dc74a4b..84b637e019ed 100644
--- a/arch/powerpc/platforms/82xx/pq2fads.c
+++ b/arch/powerpc/platforms/82xx/pq2fads.c
@@ -140,18 +140,18 @@ static void __init pq2fads_setup_arch(void)
/* Enable the serial and ethernet ports */
- clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
- setbits32(&bcsr[1], BCSR1_FETH_RST);
+ clrbits_be32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
+ setbits_be32(&bcsr[1], BCSR1_FETH_RST);
- clrbits32(&bcsr[3], BCSR3_FETHIEN2);
- setbits32(&bcsr[3], BCSR3_FETH2_RST);
+ clrbits_be32(&bcsr[3], BCSR3_FETHIEN2);
+ setbits_be32(&bcsr[3], BCSR3_FETH2_RST);
iounmap(bcsr);
init_ioports();
/* Enable external IRQs */
- clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_siumcr, 0x0c000000);
+ clrbits_be32(&cpm2_immr->im_siu_conf.siu_82xx.sc_siumcr, 0x0c000000);
pq2_init_pci();
diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c
index d8642a4afc74..d036b179dc65 100644
--- a/arch/powerpc/platforms/83xx/km83xx.c
+++ b/arch/powerpc/platforms/83xx/km83xx.c
@@ -101,19 +101,19 @@ static void quirk_mpc8360e_qe_enet10(void)
* UCC1: write 0b11 to bits 18:19
* at address IMMRBAR+0x14A8
*/
- setbits32((base + 0xa8), 0x00003000);
+ setbits_be32((base + 0xa8), 0x00003000);
/*
* UCC2 option 1: write 0b11 to bits 4:5
* at address IMMRBAR+0x14A8
*/
- setbits32((base + 0xa8), 0x0c000000);
+ setbits_be32((base + 0xa8), 0x0c000000);
/*
* UCC2 option 2: write 0b11 to bits 16:17
* at address IMMRBAR+0x14AC
*/
- setbits32((base + 0xac), 0x0000c000);
+ setbits_be32((base + 0xac), 0x0000c000);
}
iounmap(base);
of_node_put(np_par);
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index fd44dd03e1f3..83a5e27e2f63 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -118,7 +118,7 @@ static void __init mpc836x_mds_setup_arch(void)
* IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
* IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
*/
- setbits32(immap, 0x0c003000);
+ setbits_be32(immap, 0x0c003000);
/*
* IMMR + 0x14AC[20:27] = 10101010
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index d7e440e6dba3..52b4fb179c9e 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -262,7 +262,7 @@ static void __init mpc85xx_mds_qe_init(void)
* and QE12 for QE MII management signals in PMUXCR
* register.
*/
- setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
+ setbits_be32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
MPC85xx_PMUXCR_QE(3) |
MPC85xx_PMUXCR_QE(9) |
MPC85xx_PMUXCR_QE(12));
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
index f05325f0cc03..926d0f9dc29d 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
@@ -60,9 +60,9 @@ static void mpc85xx_freeze_time_base(bool freeze)
mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
if (freeze)
- setbits32(&guts->devdisr, mask);
+ setbits_be32(&guts->devdisr, mask);
else
- clrbits32(&guts->devdisr, mask);
+ clrbits_be32(&guts->devdisr, mask);
in_be32(&guts->devdisr);
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index 10069503e39f..fdea28dd90dd 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -115,7 +115,7 @@ static void __init mpc85xx_rdb_setup_arch(void)
* and QE12 for QE MII management singals in PMUXCR
* register.
*/
- setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
+ setbits_be32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
MPC85xx_PMUXCR_QE(3) |
MPC85xx_PMUXCR_QE(9) |
MPC85xx_PMUXCR_QE(12));
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 9fb57f78cdbe..88860b270a7b 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -405,11 +405,11 @@ void p1022ds_set_pixel_clock(unsigned int pixclock)
pxclk = clamp_t(u32, pxclk, 2, 255);
/* Disable the pixel clock, and set it to non-inverted and no delay */
- clrbits32(&guts->clkdvdr,
+ clrbits_be32(&guts->clkdvdr,
CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
/* Enable the clock and set the pxclk */
- setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
+ setbits_be32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
iounmap(guts);
}
diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c
index 276e00ab3dde..051713cf6c0e 100644
--- a/arch/powerpc/platforms/85xx/p1022_rdk.c
+++ b/arch/powerpc/platforms/85xx/p1022_rdk.c
@@ -75,11 +75,11 @@ void p1022rdk_set_pixel_clock(unsigned int pixclock)
pxclk = clamp_t(u32, pxclk, 2, 255);
/* Disable the pixel clock, and set it to non-inverted and no delay */
- clrbits32(&guts->clkdvdr,
+ clrbits_be32(&guts->clkdvdr,
CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
/* Enable the clock and set the pxclk */
- setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
+ setbits_be32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
iounmap(guts);
}
diff --git a/arch/powerpc/platforms/85xx/t1042rdb_diu.c b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
index dac36ba82fea..e78970d2b292 100644
--- a/arch/powerpc/platforms/85xx/t1042rdb_diu.c
+++ b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
@@ -114,11 +114,11 @@ static void t1042rdb_set_pixel_clock(unsigned int pixclock)
pxclk = clamp_t(u32, pxclk, 2, 255);
/* Disable the pixel clock, and set it to non-inverted and no delay */
- clrbits32(scfg + CCSR_SCFG_PIXCLKCR,
+ clrbits_be32(scfg + CCSR_SCFG_PIXCLKCR,
PIXCLKCR_PXCKEN | PIXCLKCR_PXCKDLY | PIXCLKCR_PXCLK_MASK);
/* Enable the clock and set the pxclk */
- setbits32(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16));
+ setbits_be32(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16));
iounmap(scfg);
}
diff --git a/arch/powerpc/platforms/85xx/twr_p102x.c b/arch/powerpc/platforms/85xx/twr_p102x.c
index 360f6253e9ff..5c385ebf6cac 100644
--- a/arch/powerpc/platforms/85xx/twr_p102x.c
+++ b/arch/powerpc/platforms/85xx/twr_p102x.c
@@ -95,7 +95,7 @@ static void __init twr_p1025_setup_arch(void)
* and QE12 for QE MII management signals in PMUXCR
* register.
* Set QE mux bits in PMUXCR */
- setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
+ setbits_be32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
MPC85xx_PMUXCR_QE(3) |
MPC85xx_PMUXCR_QE(9) |
MPC85xx_PMUXCR_QE(12));
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index a5d73fabe4d1..8b6c12f634c4 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -261,11 +261,11 @@ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
pxclk = clamp_t(u32, pxclk, 2, 31);
/* Disable the pixel clock, and set it to non-inverted and no delay */
- clrbits32(&guts->clkdvdr,
+ clrbits_be32(&guts->clkdvdr,
CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
/* Enable the clock and set the pxclk */
- setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
+ setbits_be32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
iounmap(guts);
}
diff --git a/arch/powerpc/platforms/8xx/adder875.c b/arch/powerpc/platforms/8xx/adder875.c
index bcef9f66191e..7bfae1617cfa 100644
--- a/arch/powerpc/platforms/8xx/adder875.c
+++ b/arch/powerpc/platforms/8xx/adder875.c
@@ -77,7 +77,7 @@ static void __init init_ioports(void)
cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
/* Set FEC1 and FEC2 to MII mode */
- clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
+ clrbits_be32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
}
static void __init adder875_setup(void)
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 027c42d8966c..355b2974123d 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -103,7 +103,7 @@ void __init mpc8xx_calibrate_decr(void)
/* Force all 8xx processors to use divide by 16 processor clock. */
clk_r2 = immr_map(im_clkrst);
- setbits32(&clk_r2->car_sccr, 0x02000000);
+ setbits_be32(&clk_r2->car_sccr, 0x02000000);
immr_unmap(clk_r2);
/* Processor frequency is MHz.
@@ -203,7 +203,7 @@ void __noreturn mpc8xx_restart(char *cmd)
local_irq_disable();
- setbits32(&clk_r->car_plprcr, 0x00000080);
+ setbits_be32(&clk_r->car_plprcr, 0x00000080);
/* Clear the ME bit in MSR to cause checkstop on machine check
*/
mtmsr(mfmsr() & ~0x1000);
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index 8d02f5ff4481..88c611ecee0a 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -87,7 +87,7 @@ static void __init init_ioports(void)
cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK2, CPM_CLK_RX);
/* Set FEC1 and FEC2 to MII mode */
- clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
+ clrbits_be32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
}
static void __init mpc86xads_setup_arch(void)
@@ -112,7 +112,7 @@ static void __init mpc86xads_setup_arch(void)
return;
}
- clrbits32(bcsr_io, BCSR1_RS232EN_1 | BCSR1_RS232EN_2 | BCSR1_ETHEN);
+ clrbits_be32(bcsr_io, BCSR1_RS232EN_1 | BCSR1_RS232EN_2 | BCSR1_ETHEN);
iounmap(bcsr_io);
}
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index a0c83c1905c6..17e10250830b 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -123,7 +123,7 @@ static void __init init_ioports(void)
cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_RX);
/* Set FEC1 and FEC2 to MII mode */
- clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
+ clrbits_be32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
}
static void __init mpc885ads_setup_arch(void)
@@ -148,33 +148,33 @@ static void __init mpc885ads_setup_arch(void)
return;
}
- clrbits32(&bcsr[1], BCSR1_RS232EN_1);
+ clrbits_be32(&bcsr[1], BCSR1_RS232EN_1);
#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
- setbits32(&bcsr[1], BCSR1_RS232EN_2);
+ setbits_be32(&bcsr[1], BCSR1_RS232EN_2);
#else
- clrbits32(&bcsr[1], BCSR1_RS232EN_2);
+ clrbits_be32(&bcsr[1], BCSR1_RS232EN_2);
#endif
- clrbits32(bcsr5, BCSR5_MII1_EN);
- setbits32(bcsr5, BCSR5_MII1_RST);
+ clrbits_be32(bcsr5, BCSR5_MII1_EN);
+ setbits_be32(bcsr5, BCSR5_MII1_RST);
udelay(1000);
- clrbits32(bcsr5, BCSR5_MII1_RST);
+ clrbits_be32(bcsr5, BCSR5_MII1_RST);
#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
- clrbits32(bcsr5, BCSR5_MII2_EN);
- setbits32(bcsr5, BCSR5_MII2_RST);
+ clrbits_be32(bcsr5, BCSR5_MII2_EN);
+ setbits_be32(bcsr5, BCSR5_MII2_RST);
udelay(1000);
- clrbits32(bcsr5, BCSR5_MII2_RST);
+ clrbits_be32(bcsr5, BCSR5_MII2_RST);
#else
- setbits32(bcsr5, BCSR5_MII2_EN);
+ setbits_be32(bcsr5, BCSR5_MII2_EN);
#endif
#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
- clrbits32(&bcsr[4], BCSR4_ETH10_RST);
+ clrbits_be32(&bcsr[4], BCSR4_ETH10_RST);
udelay(1000);
- setbits32(&bcsr[4], BCSR4_ETH10_RST);
+ setbits_be32(&bcsr[4], BCSR4_ETH10_RST);
- setbits32(&bcsr[1], BCSR1_ETHEN);
+ setbits_be32(&bcsr[1], BCSR1_ETHEN);
np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80");
#else
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index db0be007fd06..658f972d277a 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -53,7 +53,7 @@ static void flipper_pic_mask_and_ack(struct irq_data *d)
void __iomem *io_base = irq_data_get_irq_chip_data(d);
u32 mask = 1 << irq;
- clrbits32(io_base + FLIPPER_IMR, mask);
+ clrbits_be32(io_base + FLIPPER_IMR, mask);
/* this is at least needed for RSW */
out_be32(io_base + FLIPPER_ICR, mask);
}
@@ -72,7 +72,7 @@ static void flipper_pic_mask(struct irq_data *d)
int irq = irqd_to_hwirq(d);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
- clrbits32(io_base + FLIPPER_IMR, 1 << irq);
+ clrbits_be32(io_base + FLIPPER_IMR, 1 << irq);
}
static void flipper_pic_unmask(struct irq_data *d)
@@ -80,7 +80,7 @@ static void flipper_pic_unmask(struct irq_data *d)
int irq = irqd_to_hwirq(d);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
- setbits32(io_base + FLIPPER_IMR, 1 << irq);
+ setbits_be32(io_base + FLIPPER_IMR, 1 << irq);
}
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 8112b39879d6..a5431ad4a529 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -50,7 +50,7 @@ static void hlwd_pic_mask_and_ack(struct irq_data *d)
void __iomem *io_base = irq_data_get_irq_chip_data(d);
u32 mask = 1 << irq;
- clrbits32(io_base + HW_BROADWAY_IMR, mask);
+ clrbits_be32(io_base + HW_BROADWAY_IMR, mask);
out_be32(io_base + HW_BROADWAY_ICR, mask);
}
@@ -67,7 +67,7 @@ static void hlwd_pic_mask(struct irq_data *d)
int irq = irqd_to_hwirq(d);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
- clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
+ clrbits_be32(io_base + HW_BROADWAY_IMR, 1 << irq);
}
static void hlwd_pic_unmask(struct irq_data *d)
@@ -75,10 +75,10 @@ static void hlwd_pic_unmask(struct irq_data *d)
int irq = irqd_to_hwirq(d);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
- setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
+ setbits_be32(io_base + HW_BROADWAY_IMR, 1 << irq);
/* Make sure the ARM (aka. Starlet) doesn't handle this interrupt. */
- clrbits32(io_base + HW_STARLET_IMR, 1 << irq);
+ clrbits_be32(io_base + HW_STARLET_IMR, 1 << irq);
}
diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
index 403523c061ba..f3dd1889d303 100644
--- a/arch/powerpc/platforms/embedded6xx/wii.c
+++ b/arch/powerpc/platforms/embedded6xx/wii.c
@@ -134,7 +134,7 @@ static void __init wii_setup_arch(void)
hw_gpio = wii_ioremap_hw_regs("hw_gpio", HW_GPIO_COMPATIBLE);
if (hw_gpio) {
/* turn off the front blue led and IR light */
- clrbits32(hw_gpio + HW_GPIO_OUT(0),
+ clrbits_be32(hw_gpio + HW_GPIO_OUT(0),
HW_GPIO_SLOT_LED | HW_GPIO_SENSOR_BAR);
}
}
@@ -145,7 +145,7 @@ static void __noreturn wii_restart(char *cmd)
if (hw_ctrl) {
/* clear the system reset pin to cause a reset */
- clrbits32(hw_ctrl + HW_CTRL_RESETS, HW_CTRL_RESETS_SYS);
+ clrbits_be32(hw_ctrl + HW_CTRL_RESETS, HW_CTRL_RESETS_SYS);
}
wii_spin();
}
@@ -159,13 +159,13 @@ static void wii_power_off(void)
* set the owner of the shutdown pin to ARM, because it is
* accessed through the registers for the ARM, below
*/
- clrbits32(hw_gpio + HW_GPIO_OWNER, HW_GPIO_SHUTDOWN);
+ clrbits_be32(hw_gpio + HW_GPIO_OWNER, HW_GPIO_SHUTDOWN);
/* make sure that the poweroff GPIO is configured as output */
- setbits32(hw_gpio + HW_GPIO_DIR(1), HW_GPIO_SHUTDOWN);
+ setbits_be32(hw_gpio + HW_GPIO_DIR(1), HW_GPIO_SHUTDOWN);
/* drive the poweroff GPIO high */
- setbits32(hw_gpio + HW_GPIO_OUT(1), HW_GPIO_SHUTDOWN);
+ setbits_be32(hw_gpio + HW_GPIO_OUT(1), HW_GPIO_SHUTDOWN);
}
wii_spin();
}
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 4f8dcf124828..7fcbf8c059eb 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -60,14 +60,14 @@ static void cpm_mask_irq(struct irq_data *d)
{
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
- clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
+ clrbits_be32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
}
static void cpm_unmask_irq(struct irq_data *d)
{
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
- setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
+ setbits_be32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
}
static void cpm_end_irq(struct irq_data *d)
@@ -188,7 +188,7 @@ unsigned int cpm_pic_init(void)
if (setup_irq(eirq, &cpm_error_irqaction))
printk(KERN_ERR "Could not allocate CPM error IRQ!");
- setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
+ setbits_be32(&cpic_reg->cpic_cicr, CICR_IEN);
end:
of_node_put(np);
@@ -317,14 +317,14 @@ static void cpm1_set_pin32(int port, int pin, int flags)
&mpc8xx_immr->im_cpm.cp_pedir;
if (flags & CPM_PIN_OUTPUT)
- setbits32(&iop->dir, pin);
+ setbits_be32(&iop->dir, pin);
else
- clrbits32(&iop->dir, pin);
+ clrbits_be32(&iop->dir, pin);
if (!(flags & CPM_PIN_GPIO))
- setbits32(&iop->par, pin);
+ setbits_be32(&iop->par, pin);
else
- clrbits32(&iop->par, pin);
+ clrbits_be32(&iop->par, pin);
if (port == CPM_PORTB) {
if (flags & CPM_PIN_OPENDRAIN)
@@ -335,14 +335,14 @@ static void cpm1_set_pin32(int port, int pin, int flags)
if (port == CPM_PORTE) {
if (flags & CPM_PIN_SECONDARY)
- setbits32(&iop->sor, pin);
+ setbits_be32(&iop->sor, pin);
else
- clrbits32(&iop->sor, pin);
+ clrbits_be32(&iop->sor, pin);
if (flags & CPM_PIN_OPENDRAIN)
- setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
+ setbits_be32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
else
- clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
+ clrbits_be32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
}
}
@@ -732,7 +732,7 @@ static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
spin_lock_irqsave(&cpm1_gc->lock, flags);
- setbits32(&iop->dir, pin_mask);
+ setbits_be32(&iop->dir, pin_mask);
__cpm1_gpio32_set(mm_gc, pin_mask, val);
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
@@ -750,7 +750,7 @@ static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
spin_lock_irqsave(&cpm1_gc->lock, flags);
- clrbits32(&iop->dir, pin_mask);
+ clrbits_be32(&iop->dir, pin_mask);
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
index 07718b9a2c99..e8c7a0117eed 100644
--- a/arch/powerpc/sysdev/cpm2.c
+++ b/arch/powerpc/sysdev/cpm2.c
@@ -335,22 +335,22 @@ void cpm2_set_pin(int port, int pin, int flags)
pin = 1 << (31 - pin);
if (flags & CPM_PIN_OUTPUT)
- setbits32(&iop[port].dir, pin);
+ setbits_be32(&iop[port].dir, pin);
else
- clrbits32(&iop[port].dir, pin);
+ clrbits_be32(&iop[port].dir, pin);
if (!(flags & CPM_PIN_GPIO))
- setbits32(&iop[port].par, pin);
+ setbits_be32(&iop[port].par, pin);
else
- clrbits32(&iop[port].par, pin);
+ clrbits_be32(&iop[port].par, pin);
if (flags & CPM_PIN_SECONDARY)
- setbits32(&iop[port].sor, pin);
+ setbits_be32(&iop[port].sor, pin);
else
- clrbits32(&iop[port].sor, pin);
+ clrbits_be32(&iop[port].sor, pin);
if (flags & CPM_PIN_OPENDRAIN)
- setbits32(&iop[port].odr, pin);
+ setbits_be32(&iop[port].odr, pin);
else
- clrbits32(&iop[port].odr, pin);
+ clrbits_be32(&iop[port].odr, pin);
}
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index b74508175b67..8f4fba3067c9 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -165,7 +165,7 @@ static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
spin_lock_irqsave(&cpm2_gc->lock, flags);
- setbits32(&iop->dir, pin_mask);
+ setbits_be32(&iop->dir, pin_mask);
__cpm2_gpio32_set(mm_gc, pin_mask, val);
spin_unlock_irqrestore(&cpm2_gc->lock, flags);
@@ -183,7 +183,7 @@ static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
spin_lock_irqsave(&cpm2_gc->lock, flags);
- clrbits32(&iop->dir, pin_mask);
+ clrbits_be32(&iop->dir, pin_mask);
spin_unlock_irqrestore(&cpm2_gc->lock, flags);
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
index c27058e5df26..2a99e56d3c7d 100644
--- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
@@ -124,23 +124,23 @@ static int mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
switch (ways) {
case LOCK_WAYS_EIGHTH:
- setbits32(&l2ctlr->ctl,
+ setbits_be32(&l2ctlr->ctl,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH);
break;
case LOCK_WAYS_TWO_EIGHTH:
- setbits32(&l2ctlr->ctl,
+ setbits_be32(&l2ctlr->ctl,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_QUART);
break;
case LOCK_WAYS_HALF:
- setbits32(&l2ctlr->ctl,
+ setbits_be32(&l2ctlr->ctl,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF);
break;
case LOCK_WAYS_FULL:
default:
- setbits32(&l2ctlr->ctl,
+ setbits_be32(&l2ctlr->ctl,
L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL);
break;
}
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 5340a483cf55..0264f8c67a96 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -192,7 +192,7 @@ static int fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl,
struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
/* clear event registers */
- setbits32(&lbc->ltesr, LTESR_CLEAR);
+ setbits_be32(&lbc->ltesr, LTESR_CLEAR);
out_be32(&lbc->lteatr, 0);
out_be32(&lbc->ltear, 0);
out_be32(&lbc->lteccr, LTECCR_CLEAR);
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 918be816b097..e8488c9c284c 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1196,11 +1196,11 @@ static int fsl_pci_pme_probe(struct pci_controller *hose)
pci = hose->private_data;
/* Enable PTOD, ENL23D & EXL23D */
- clrbits32(&pci->pex_pme_mes_disr,
+ clrbits_be32(&pci->pex_pme_mes_disr,
PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
out_be32(&pci->pex_pme_mes_ier, 0);
- setbits32(&pci->pex_pme_mes_ier,
+ setbits_be32(&pci->pex_pme_mes_ier,
PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
/* PME Enable */
@@ -1218,7 +1218,7 @@ static void send_pme_turnoff_message(struct pci_controller *hose)
int i;
/* Send PME_Turn_Off Message Request */
- setbits32(&pci->pex_pmcr, PEX_PMCR_PTOMR);
+ setbits_be32(&pci->pex_pmcr, PEX_PMCR_PTOMR);
/* Wait trun off done */
for (i = 0; i < 150; i++) {
@@ -1254,7 +1254,7 @@ static void fsl_pci_syscore_do_resume(struct pci_controller *hose)
int i;
/* Send Exit L2 State Message */
- setbits32(&pci->pex_pmcr, PEX_PMCR_EXL2S);
+ setbits_be32(&pci->pex_pmcr, PEX_PMCR_EXL2S);
/* Wait exit done */
for (i = 0; i < 150; i++) {
diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c
index 232225e7f863..ff29fa6af01c 100644
--- a/arch/powerpc/sysdev/fsl_pmc.c
+++ b/arch/powerpc/sysdev/fsl_pmc.c
@@ -37,7 +37,7 @@ static int pmc_suspend_enter(suspend_state_t state)
{
int ret;
- setbits32(&pmc_regs->pmcsr, PMCSR_SLP);
+ setbits_be32(&pmc_regs->pmcsr, PMCSR_SLP);
/* At this point, the CPU is asleep. */
/* Upon resume, wait for SLP bit to be clear. */
diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c
index 9259a94f70e1..fce703c400e6 100644
--- a/arch/powerpc/sysdev/fsl_rcpm.c
+++ b/arch/powerpc/sysdev/fsl_rcpm.c
@@ -33,10 +33,10 @@ static void rcpm_v1_irq_mask(int cpu)
int hw_cpu = get_hard_smp_processor_id(cpu);
unsigned int mask = 1 << hw_cpu;
- setbits32(&rcpm_v1_regs->cpmimr, mask);
- setbits32(&rcpm_v1_regs->cpmcimr, mask);
- setbits32(&rcpm_v1_regs->cpmmcmr, mask);
- setbits32(&rcpm_v1_regs->cpmnmimr, mask);
+ setbits_be32(&rcpm_v1_regs->cpmimr, mask);
+ setbits_be32(&rcpm_v1_regs->cpmcimr, mask);
+ setbits_be32(&rcpm_v1_regs->cpmmcmr, mask);
+ setbits_be32(&rcpm_v1_regs->cpmnmimr, mask);
}
static void rcpm_v2_irq_mask(int cpu)
@@ -44,10 +44,10 @@ static void rcpm_v2_irq_mask(int cpu)
int hw_cpu = get_hard_smp_processor_id(cpu);
unsigned int mask = 1 << hw_cpu;
- setbits32(&rcpm_v2_regs->tpmimr0, mask);
- setbits32(&rcpm_v2_regs->tpmcimr0, mask);
- setbits32(&rcpm_v2_regs->tpmmcmr0, mask);
- setbits32(&rcpm_v2_regs->tpmnmimr0, mask);
+ setbits_be32(&rcpm_v2_regs->tpmimr0, mask);
+ setbits_be32(&rcpm_v2_regs->tpmcimr0, mask);
+ setbits_be32(&rcpm_v2_regs->tpmmcmr0, mask);
+ setbits_be32(&rcpm_v2_regs->tpmnmimr0, mask);
}
static void rcpm_v1_irq_unmask(int cpu)
@@ -55,10 +55,10 @@ static void rcpm_v1_irq_unmask(int cpu)
int hw_cpu = get_hard_smp_processor_id(cpu);
unsigned int mask = 1 << hw_cpu;
- clrbits32(&rcpm_v1_regs->cpmimr, mask);
- clrbits32(&rcpm_v1_regs->cpmcimr, mask);
- clrbits32(&rcpm_v1_regs->cpmmcmr, mask);
- clrbits32(&rcpm_v1_regs->cpmnmimr, mask);
+ clrbits_be32(&rcpm_v1_regs->cpmimr, mask);
+ clrbits_be32(&rcpm_v1_regs->cpmcimr, mask);
+ clrbits_be32(&rcpm_v1_regs->cpmmcmr, mask);
+ clrbits_be32(&rcpm_v1_regs->cpmnmimr, mask);
}
static void rcpm_v2_irq_unmask(int cpu)
@@ -66,26 +66,26 @@ static void rcpm_v2_irq_unmask(int cpu)
int hw_cpu = get_hard_smp_processor_id(cpu);
unsigned int mask = 1 << hw_cpu;
- clrbits32(&rcpm_v2_regs->tpmimr0, mask);
- clrbits32(&rcpm_v2_regs->tpmcimr0, mask);
- clrbits32(&rcpm_v2_regs->tpmmcmr0, mask);
- clrbits32(&rcpm_v2_regs->tpmnmimr0, mask);
+ clrbits_be32(&rcpm_v2_regs->tpmimr0, mask);
+ clrbits_be32(&rcpm_v2_regs->tpmcimr0, mask);
+ clrbits_be32(&rcpm_v2_regs->tpmmcmr0, mask);
+ clrbits_be32(&rcpm_v2_regs->tpmnmimr0, mask);
}
static void rcpm_v1_set_ip_power(bool enable, u32 mask)
{
if (enable)
- setbits32(&rcpm_v1_regs->ippdexpcr, mask);
+ setbits_be32(&rcpm_v1_regs->ippdexpcr, mask);
else
- clrbits32(&rcpm_v1_regs->ippdexpcr, mask);
+ clrbits_be32(&rcpm_v1_regs->ippdexpcr, mask);
}
static void rcpm_v2_set_ip_power(bool enable, u32 mask)
{
if (enable)
- setbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
+ setbits_be32(&rcpm_v2_regs->ippdexpcr[0], mask);
else
- clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
+ clrbits_be32(&rcpm_v2_regs->ippdexpcr[0], mask);
}
static void rcpm_v1_cpu_enter_state(int cpu, int state)
@@ -95,10 +95,10 @@ static void rcpm_v1_cpu_enter_state(int cpu, int state)
switch (state) {
case E500_PM_PH10:
- setbits32(&rcpm_v1_regs->cdozcr, mask);
+ setbits_be32(&rcpm_v1_regs->cdozcr, mask);
break;
case E500_PM_PH15:
- setbits32(&rcpm_v1_regs->cnapcr, mask);
+ setbits_be32(&rcpm_v1_regs->cnapcr, mask);
break;
default:
pr_warn("Unknown cpu PM state (%d)\n", state);
@@ -114,16 +114,16 @@ static void rcpm_v2_cpu_enter_state(int cpu, int state)
switch (state) {
case E500_PM_PH10:
/* one bit corresponds to one thread for PH10 of 6500 */
- setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu);
+ setbits_be32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu);
break;
case E500_PM_PH15:
- setbits32(&rcpm_v2_regs->pcph15setr, mask);
+ setbits_be32(&rcpm_v2_regs->pcph15setr, mask);
break;
case E500_PM_PH20:
- setbits32(&rcpm_v2_regs->pcph20setr, mask);
+ setbits_be32(&rcpm_v2_regs->pcph20setr, mask);
break;
case E500_PM_PH30:
- setbits32(&rcpm_v2_regs->pcph30setr, mask);
+ setbits_be32(&rcpm_v2_regs->pcph30setr, mask);
break;
default:
pr_warn("Unknown cpu PM state (%d)\n", state);
@@ -172,10 +172,10 @@ static void rcpm_v1_cpu_exit_state(int cpu, int state)
switch (state) {
case E500_PM_PH10:
- clrbits32(&rcpm_v1_regs->cdozcr, mask);
+ clrbits_be32(&rcpm_v1_regs->cdozcr, mask);
break;
case E500_PM_PH15:
- clrbits32(&rcpm_v1_regs->cnapcr, mask);
+ clrbits_be32(&rcpm_v1_regs->cnapcr, mask);
break;
default:
pr_warn("Unknown cpu PM state (%d)\n", state);
@@ -196,16 +196,16 @@ static void rcpm_v2_cpu_exit_state(int cpu, int state)
switch (state) {
case E500_PM_PH10:
- setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu);
+ setbits_be32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu);
break;
case E500_PM_PH15:
- setbits32(&rcpm_v2_regs->pcph15clrr, mask);
+ setbits_be32(&rcpm_v2_regs->pcph15clrr, mask);
break;
case E500_PM_PH20:
- setbits32(&rcpm_v2_regs->pcph20clrr, mask);
+ setbits_be32(&rcpm_v2_regs->pcph20clrr, mask);
break;
case E500_PM_PH30:
- setbits32(&rcpm_v2_regs->pcph30clrr, mask);
+ setbits_be32(&rcpm_v2_regs->pcph30clrr, mask);
break;
default:
pr_warn("Unknown cpu PM state (%d)\n", state);
@@ -226,7 +226,7 @@ static int rcpm_v1_plat_enter_state(int state)
switch (state) {
case PLAT_PM_SLEEP:
- setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP);
+ setbits_be32(pmcsr_reg, RCPM_POWMGTCSR_SLP);
/* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */
result = spin_event_timeout(
@@ -253,9 +253,9 @@ static int rcpm_v2_plat_enter_state(int state)
switch (state) {
case PLAT_PM_LPM20:
/* clear previous LPM20 status */
- setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST);
+ setbits_be32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST);
/* enter LPM20 status */
- setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ);
+ setbits_be32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ);
/* At this point, the device is in LPM20 status. */
@@ -291,9 +291,9 @@ static void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze)
if (freeze) {
mask = in_be32(tben_reg);
- clrbits32(tben_reg, mask);
+ clrbits_be32(tben_reg, mask);
} else {
- setbits32(tben_reg, mask);
+ setbits_be32(tben_reg, mask);
}
/* read back to push the previous write */
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 5011ffea4e4b..891e11d12222 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -668,10 +668,10 @@ int fsl_rio_setup(struct platform_device *dev)
out_be32(priv->regs_win
+ RIO_CCSR + i*0x20, 0);
/* Set 1x lane */
- setbits32(priv->regs_win
+ setbits_be32(priv->regs_win
+ RIO_CCSR + i*0x20, 0x02000000);
/* Enable ports */
- setbits32(priv->regs_win
+ setbits_be32(priv->regs_win
+ RIO_CCSR + i*0x20, 0x00600000);
msleep(100);
if (in_be32((priv->regs_win
diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c
index 88b35a3dcdc5..1a2567df9afc 100644
--- a/arch/powerpc/sysdev/fsl_rmu.c
+++ b/arch/powerpc/sysdev/fsl_rmu.c
@@ -355,7 +355,7 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
dmsg->sid, dmsg->tid,
dmsg->info);
}
- setbits32(&fsl_dbell->dbell_regs->dmr, DOORBELL_DMR_DI);
+ setbits_be32(&fsl_dbell->dbell_regs->dmr, DOORBELL_DMR_DI);
out_be32(&fsl_dbell->dbell_regs->dsr, DOORBELL_DSR_DIQI);
}
@@ -909,10 +909,10 @@ fsl_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
out_be32(&rmu->msg_regs->imr, 0x001b0060);
/* Set number of queue entries */
- setbits32(&rmu->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);
+ setbits_be32(&rmu->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);
/* Now enable the unit */
- setbits32(&rmu->msg_regs->imr, 0x1);
+ setbits_be32(&rmu->msg_regs->imr, 0x1);
out:
return rc;
@@ -1015,7 +1015,7 @@ void *fsl_get_inb_message(struct rio_mport *mport, int mbox)
rmu->msg_rx_ring.virt_buffer[buf_idx] = NULL;
out1:
- setbits32(&rmu->msg_regs->imr, RIO_MSG_IMR_MI);
+ setbits_be32(&rmu->msg_regs->imr, RIO_MSG_IMR_MI);
out2:
return buf;
diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c
index 87e7c42777a8..5cc8216a85e5 100644
--- a/arch/powerpc/sysdev/mpic_timer.c
+++ b/arch/powerpc/sysdev/mpic_timer.c
@@ -154,7 +154,7 @@ static int set_cascade_timer(struct timer_group_priv *priv, u64 ticks,
tcr = casc_priv->tcr_value |
(casc_priv->tcr_value << MPIC_TIMER_TCR_ROVR_OFFSET);
- setbits32(priv->group_tcr, tcr);
+ setbits_be32(priv->group_tcr, tcr);
tmp_ticks = div_u64_rem(ticks, MAX_TICKS_CASCADE, &rem_ticks);
@@ -253,7 +253,7 @@ void mpic_start_timer(struct mpic_timer *handle)
struct timer_group_priv *priv = container_of(handle,
struct timer_group_priv, timer[handle->num]);
- clrbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
+ clrbits_be32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
}
EXPORT_SYMBOL(mpic_start_timer);
@@ -269,7 +269,7 @@ void mpic_stop_timer(struct mpic_timer *handle)
struct timer_group_priv, timer[handle->num]);
struct cascade_priv *casc_priv;
- setbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
+ setbits_be32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
casc_priv = priv->timer[handle->num].cascade_handle;
if (casc_priv) {
@@ -340,7 +340,7 @@ void mpic_free_timer(struct mpic_timer *handle)
u32 tcr;
tcr = casc_priv->tcr_value | (casc_priv->tcr_value <<
MPIC_TIMER_TCR_ROVR_OFFSET);
- clrbits32(priv->group_tcr, tcr);
+ clrbits_be32(priv->group_tcr, tcr);
priv->idle |= casc_priv->cascade_map;
priv->timer[handle->num].cascade_handle = NULL;
} else {
@@ -508,7 +508,7 @@ static void timer_group_init(struct device_node *np)
/* Init FSL timer hardware */
if (priv->flags & FSL_GLOBAL_TIMER)
- setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
+ setbits_be32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
list_add_tail(&priv->node, &timer_group_list);
@@ -531,7 +531,7 @@ static void mpic_timer_resume(void)
list_for_each_entry(priv, &timer_group_list, node) {
/* Init FSL timer hardware */
if (priv->flags & FSL_GLOBAL_TIMER)
- setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
+ setbits_be32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
}
}
--
2.16.4
^ permalink raw reply related
* Re: BUG: jumbo frames broken after commit xen-netfront: Fix race between device setup and open
From: Brandon Holbrook @ 2018-09-24 18:58 UTC (permalink / raw)
To: ross.lagerwall@citrix.com; +Cc: netdev@vger.kernel.org
We are experiencing this bug on stable Gentoo (4.14.67) on EC2. I see the original "Fix race between device setup and open" commit is present in 4.14, but the fix commit(s) have not yet been backported. As your fix seems to have resolved the issue and not caused any other ill effects, will you please?
Thanks!
-Brandon Holbrook
^ permalink raw reply
* Re: [PATCH net] af_key: free SKBs under RCU protection
From: stranche @ 2018-09-24 18:46 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, steffen.klassert
In-Reply-To: <9a3d8036-9f8c-6e8b-f16c-7c278c448db3@gmail.com>
On 2018-09-23 11:15, Eric Dumazet wrote:
> On 09/20/2018 12:25 PM, stranche@codeaurora.org wrote:
>
>> Perhaps a cleaner solution here is to always clone the SKB in
>> pfkey_broadcast_one(). That will ensure that the two kfree_skb() calls
>> in pfkey_broadcast() will never be passed an SKB with sock_rfree() as
>> its destructor, and we can avoid this race condition.
>
> Yes, this whole idea of avoiding the cloning is brain dead.
>
> Better play safe and having a straightforward implementation.
>
> I suggest something like this (I could not reproduce the bug with the
> syzkaller repro)
>
> Note that I removed the sock_hold(sk)/sock_put(sk) pair as this is
> useless.
> The only time GFP_KERNEL might be used is when the sk is already owned
> by the caller.
>
>
> net/key/af_key.c | 40 +++++++++++++++-------------------------
> 1 file changed, 15 insertions(+), 25 deletions(-)
Hi Eric,
That patch works like a charm. Could you upload that as a formal patch?
Thanks for all your help with this.
^ permalink raw reply
* Re: [PATCH net 2/2] net: phy: fix WoL handling when suspending the PHY
From: Florian Fainelli @ 2018-09-24 18:21 UTC (permalink / raw)
To: Heiner Kallweit, Andrew Lunn, David Miller,
Realtek linux nic maintainers
Cc: netdev@vger.kernel.org
In-Reply-To: <fbc8dd5f-beee-4177-d25f-303d095505a6@gmail.com>
On 09/24/2018 11:11 AM, Heiner Kallweit wrote:
> Core of the problem is that phy_suspend() suspends the PHY when it
> should not because of WoL. phy_suspend() checks for WoL already, but
> this works only if the PHY driver handles WoL (what is rarely the case).
> Typically WoL is handled by the MAC driver.
>
> This patch uses new member wol_enabled of struct net_device as
> additional criteria in the check when not to suspend the PHY because
> of WoL.
>
> Last but not least change phy_detach() to call phy_suspend() before
> attached_dev is set to NULL. phy_suspend() accesses attached_dev
> when checking whether the MAC driver activated WoL.
Looks fine to me, just a few nits/questions down below:
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Fixes: f1e911d5d0df ("r8169: add basic phylib support")
> Fixes: e8cfd9d6c772 ("net: phy: call state machine synchronously in phy_stop")
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
> drivers/net/phy/phy_device.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index af64a9320..6c0195e53 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -93,7 +93,12 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
> if (!netdev)
> return !phydev->suspended;
>
> - /* Don't suspend PHY if the attached netdev parent may wakeup.
> + if (netdev->wol_enabled)
> + return false;
> +
> + /* As lang as not all affected network drivers support the
> + * wol_enabled flag, let's check for hints that WoL is enabled.
Typo: as long (sorry for being that nitpicky).
> + * Don't suspend PHY if the attached netdev parent may wakeup.
> * The parent may point to a PCI device, as in tg3 driver.
> */
> if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
> @@ -1132,9 +1137,9 @@ void phy_detach(struct phy_device *phydev)
> sysfs_remove_link(&dev->dev.kobj, "phydev");
> sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev");
> }
> + phy_suspend(phydev);
> phydev->attached_dev->phydev = NULL;
> phydev->attached_dev = NULL;
> - phy_suspend(phydev);
> phydev->phylink = NULL;
>
> phy_led_triggers_unregister(phydev);
> @@ -1168,12 +1173,13 @@ EXPORT_SYMBOL(phy_detach);
> int phy_suspend(struct phy_device *phydev)
> {
> struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
> + struct net_device *netdev = phydev->attached_dev;
> struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> int ret = 0;
>
> /* If the device has WOL enabled, we cannot suspend the PHY */
> phy_ethtool_get_wol(phydev, &wol);
> - if (wol.wolopts)
> + if (wol.wolopts || (netdev && netdev->wol_enabled))
Since you moved the phydev->attached_dev assignment to be after
phy_suspend(), do you really need to check for netdev here? Is there
another code path you found that might be running phy_suspend() with a
disconnected PHY? Not a problem per-se, just wondering.
--
Florian
^ permalink raw reply
* Re: [PATCH] Documentation: Add HOWTO Korean translation into BPF and XDP Reference Guide.
From: Jonathan Corbet @ 2018-09-24 18:20 UTC (permalink / raw)
To: Changan Song; +Cc: netdev
In-Reply-To: <20180921042238.19582-1-csongxdp@gmail.com>
On Fri, 21 Sep 2018 13:22:38 +0900
Changan Song <csongxdp@gmail.com> wrote:
> Signed-off-by: Changan Song <csongxdp@gmail.com>
> ---
> Documentation/translations/ko_KR/bpf-xdp.txt | 3511 ++++++++++++++++++
> 1 file changed, 3511 insertions(+)
> create mode 100644 Documentation/translations/ko_KR/bpf-xdp.txt
I can't judge the quality of the translation, of course, but I do have a
couple of related questions:
- Since you're adding a new document, could you please format it as RST
and add it to index.rst with the other Korean translations? The
original will have been in RST, so this should be relatively easy to
do.
- The original document has a copyright assertion but no associated
license. Do we know what the license is? I assume it's something
that is free and GPL-compatible, but that would be good to know for
sure.
Thanks for doing this work,
jon
^ permalink raw reply
* [PATCH net 2/2] net: phy: fix WoL handling when suspending the PHY
From: Heiner Kallweit @ 2018-09-24 18:11 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, David Miller,
Realtek linux nic maintainers
Cc: netdev@vger.kernel.org
In-Reply-To: <a32b98eb-3071-2269-ab95-a44f90866912@gmail.com>
Core of the problem is that phy_suspend() suspends the PHY when it
should not because of WoL. phy_suspend() checks for WoL already, but
this works only if the PHY driver handles WoL (what is rarely the case).
Typically WoL is handled by the MAC driver.
This patch uses new member wol_enabled of struct net_device as
additional criteria in the check when not to suspend the PHY because
of WoL.
Last but not least change phy_detach() to call phy_suspend() before
attached_dev is set to NULL. phy_suspend() accesses attached_dev
when checking whether the MAC driver activated WoL.
Fixes: f1e911d5d0df ("r8169: add basic phylib support")
Fixes: e8cfd9d6c772 ("net: phy: call state machine synchronously in phy_stop")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/phy/phy_device.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index af64a9320..6c0195e53 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -93,7 +93,12 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
if (!netdev)
return !phydev->suspended;
- /* Don't suspend PHY if the attached netdev parent may wakeup.
+ if (netdev->wol_enabled)
+ return false;
+
+ /* As lang as not all affected network drivers support the
+ * wol_enabled flag, let's check for hints that WoL is enabled.
+ * Don't suspend PHY if the attached netdev parent may wakeup.
* The parent may point to a PCI device, as in tg3 driver.
*/
if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
@@ -1132,9 +1137,9 @@ void phy_detach(struct phy_device *phydev)
sysfs_remove_link(&dev->dev.kobj, "phydev");
sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev");
}
+ phy_suspend(phydev);
phydev->attached_dev->phydev = NULL;
phydev->attached_dev = NULL;
- phy_suspend(phydev);
phydev->phylink = NULL;
phy_led_triggers_unregister(phydev);
@@ -1168,12 +1173,13 @@ EXPORT_SYMBOL(phy_detach);
int phy_suspend(struct phy_device *phydev)
{
struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
+ struct net_device *netdev = phydev->attached_dev;
struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
int ret = 0;
/* If the device has WOL enabled, we cannot suspend the PHY */
phy_ethtool_get_wol(phydev, &wol);
- if (wol.wolopts)
+ if (wol.wolopts || (netdev && netdev->wol_enabled))
return -EBUSY;
if (phydev->drv && phydrv->suspend)
--
2.19.0
^ permalink raw reply related
* [PATCH net 1/2] net: core: add member wol_enabled to struct net_device
From: Heiner Kallweit @ 2018-09-24 18:09 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, David Miller,
Realtek linux nic maintainers
Cc: netdev@vger.kernel.org
In-Reply-To: <a32b98eb-3071-2269-ab95-a44f90866912@gmail.com>
Add flag wol_enabled to struct net_device indicating whether
Wake-on-LAN is enabled. As first user phy_suspend() will use it to
decide whether PHY can be suspended or not.
Fixes: f1e911d5d0df ("r8169: add basic phylib support")
Fixes: e8cfd9d6c772 ("net: phy: call state machine synchronously in phy_stop")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
include/linux/netdevice.h | 3 +++
net/core/ethtool.c | 9 ++++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 1cbbf77a6..f5f1f1450 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1756,6 +1756,8 @@ enum netdev_priv_flags {
* switch driver and used to set the phys state of the
* switch port.
*
+ * @wol_enabled: Wake-on-LAN is enabled
+ *
* FIXME: cleanup struct net_device such that network protocol info
* moves out.
*/
@@ -2039,6 +2041,7 @@ struct net_device {
struct lock_class_key *qdisc_tx_busylock;
struct lock_class_key *qdisc_running_key;
bool proto_down;
+ unsigned wol_enabled:1;
};
#define to_net_dev(d) container_of(d, struct net_device, dev)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 9d4e56d97..86f765d42 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1395,6 +1395,7 @@ static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
static int ethtool_set_wol(struct net_device *dev, char __user *useraddr)
{
struct ethtool_wolinfo wol;
+ int ret;
if (!dev->ethtool_ops->set_wol)
return -EOPNOTSUPP;
@@ -1402,7 +1403,13 @@ static int ethtool_set_wol(struct net_device *dev, char __user *useraddr)
if (copy_from_user(&wol, useraddr, sizeof(wol)))
return -EFAULT;
- return dev->ethtool_ops->set_wol(dev, &wol);
+ ret = dev->ethtool_ops->set_wol(dev, &wol);
+ if (ret)
+ return ret;
+
+ dev->wol_enabled = !!wol.wolopts;
+
+ return 0;
}
static int ethtool_get_eee(struct net_device *dev, char __user *useraddr)
--
2.19.0
^ permalink raw reply related
* Re: [PATCHv2 bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
From: Joe Stringer @ 2018-09-24 18:09 UTC (permalink / raw)
To: daniel
Cc: Joe Stringer, ast, netdev, john fastabend, tgraf,
Martin KaFai Lau, Nitin Hande, mauricio.vasquez
In-Reply-To: <691934f3-adbc-187c-afa1-9fa9d43f95aa@iogearbox.net>
On Mon, 24 Sep 2018 at 05:51, Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> On 09/24/2018 02:12 PM, Daniel Borkmann wrote:
> > On 09/21/2018 07:10 PM, Joe Stringer wrote:
> [...]
> >> +/* bpf_sk_lookup performs the core lookup for different types of sockets,
> >> + * taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.
> >> + * Returns the socket as an 'unsigned long' to simplify the casting in the
> >> + * callers to satisfy BPF_CALL declarations.
> >> + */
> >> +static unsigned long
> >> +bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
> >> + u8 proto, u64 netns_id, u64 flags)
> >> +{
> >> + struct net *caller_net = dev_net(skb->dev);
> >
> > For sk_skb programs, are we *always* guaranteed to have a skb->dev assigned?
> >
> > This definitely holds true for tc programs, but afaik not for sk_skb ones where
> > you enable the helpers below, so this would result in a NULL ptr dereference.
> >
> >> + struct sock *sk = NULL;
> >> + u8 family = AF_UNSPEC;
> >> + struct net *net;
> >> +
> >> + family = len == sizeof(tuple->ipv4) ? AF_INET : AF_INET6;
> >> + if (unlikely(family == AF_UNSPEC || netns_id > U32_MAX || flags))
> >> + goto out;
> >> +
> >> + if (netns_id)
> >> + net = get_net_ns_by_id(caller_net, netns_id);
> >> + else
> >> + net = caller_net;
> >> + if (unlikely(!net))
> >> + goto out;
> >> + sk = sk_lookup(net, tuple, skb, family, proto);
> >> + put_net(net);
>
> Hmm, isn't this also resulting in a use-after-free on net ?
>
> Presume we use dev_net(skb->dev) as net. It does read_pnet(&dev->nd_net), which
> either gets you pnet->net when netns is configured or &init_net otherwise.
>
> I don't see where an additional reference was taken in this path, hence you'll
> get an imbalance which triggers freeing the underlying netns ..
Good catch, will fix.
^ permalink raw reply
* [PATCH net 0/2] net: phy: fix WoL handling when suspending the PHY
From: Heiner Kallweit @ 2018-09-24 18:08 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, David Miller,
Realtek linux nic maintainers
Cc: netdev@vger.kernel.org
phy_suspend doesn't always recognize that WoL is enabled and therefore
suspends the PHY when it should not. First idea to address the issue
was to reuse checks used in mdio_bus_phy_may_suspend which check
whether relevant devices are wakeup-enabled.
Florian raised some concerns because drivers may enable wakeup even if
WoL isn't enabled (e.g. certain USB network drivers).
The new approach focuses on reducing the risk to break existing stuff.
We add a flag wol_enabled to struct net_device which is set in
ethtool_set_wol(). Then this flag is checked in phy_suspend().
This doesn't cover 100% of the cases yet (e.g. if WoL is enabled w/o
explicit configuration), but it covers the most relevant cases with
very little risk of regressions.
Heiner Kallweit (2):
net: core: add member wol_enabled to struct net_device
net: phy: fix WoL handling when suspending the PHY
drivers/net/phy/phy_device.c | 12 +++++++++---
include/linux/netdevice.h | 3 +++
net/core/ethtool.c | 9 ++++++++-
3 files changed, 20 insertions(+), 4 deletions(-)
--
2.19.0
^ permalink raw reply
* Re: [PATCHv2 bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
From: Joe Stringer @ 2018-09-24 18:05 UTC (permalink / raw)
To: daniel
Cc: Joe Stringer, ast, netdev, john fastabend, tgraf,
Martin KaFai Lau, Nitin Hande, mauricio.vasquez
In-Reply-To: <e808c3a0-dfe5-855c-6d92-da89d9db2adb@iogearbox.net>
On Mon, 24 Sep 2018 at 05:38, Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> On 09/24/2018 02:12 PM, Daniel Borkmann wrote:
> > Hi Joe,
> >
> > couple of comments inline:
> >
> > On 09/21/2018 07:10 PM, Joe Stringer wrote:
> >> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> >> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> >> socket listening on this host, and returns a socket pointer which the
> >> BPF program can then access to determine, for instance, whether to
> >> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> >> socket, so when a BPF program makes use of this function, it must
> >> subsequently pass the returned pointer into the newly added sk_release()
> >> to return the reference.
> >>
> >> By way of example, the following pseudocode would filter inbound
> >> connections at XDP if there is no corresponding service listening for
> >> the traffic:
> >>
> >> struct bpf_sock_tuple tuple;
> >> struct bpf_sock_ops *sk;
> >>
> >> populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> >> sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> >> if (!sk) {
> >> // Couldn't find a socket listening for this traffic. Drop.
> >> return TC_ACT_SHOT;
> >> }
> >> bpf_sk_release(sk, 0);
> >> return TC_ACT_OK;
> >>
> >> Signed-off-by: Joe Stringer <joe@wand.net.nz>
> >>
> >> ---
> >>
> >> v2: Rework 'struct bpf_sock_tuple' to allow passing a packet pointer
> >> Limit netns_id field to 32 bits
> >> Fix compile error with CONFIG_IPV6 enabled
> >> Allow direct packet access from helper
> >> ---
> >> include/uapi/linux/bpf.h | 57 ++++++++-
> >> kernel/bpf/verifier.c | 8 +-
> >> net/core/filter.c | 149 ++++++++++++++++++++++
> >> tools/include/uapi/linux/bpf.h | 57 ++++++++-
> >> tools/testing/selftests/bpf/bpf_helpers.h | 12 ++
> >> 5 files changed, 280 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> >> index aa5ccd2385ed..620adbb09a94 100644
> >> --- a/include/uapi/linux/bpf.h
> >> +++ b/include/uapi/linux/bpf.h
> >> @@ -2143,6 +2143,41 @@ union bpf_attr {
> >> * request in the skb.
> >> * Return
> >> * 0 on success, or a negative error in case of failure.
> >> + *
> >> + * struct bpf_sock_ops *bpf_sk_lookup_tcp(ctx, tuple, tuple_size, netns, flags)
> >
> > Nit: could you add proper signature like in other cases that are documented?
> >
> >> + * Decription
> >> + * Look for TCP socket matching 'tuple'. The return value must
> >> + * be checked, and if non-NULL, released via bpf_sk_release().
> >> + * @ctx: pointer to ctx
> >> + * @tuple: pointer to struct bpf_sock_tuple
> >> + * @tuple_size: size of the tuple
> >> + * @netns: network namespace id
> >> + * @flags: flags value
> >
> > Should probably say in all three cases that it's unused right now and reserved
> > for future.
>
> I think the two lookup helpers here also need to have a better documentation in
> terms of semantics wrt netns, so it definitely needs to be documented when it's
> derived from the skb's dev and when netns is used.
Good point, maybe some text like this:
If 'netns' is 0, then the netns associated with the ctx will be used.
For the tc hooks, this is the netns of the device in the skb. For
socket hooks, this is the netns of the socket. If netns is nonzero,
then this is the netns id relative to the netns associated with the
ctx.
> >> + * Return
> >> + * pointer to socket ops on success, or
> >> + * NULL in case of failure
> >> + *
> >> + * struct bpf_sock_ops *bpf_sk_lookup_udp(ctx, tuple, tuple_size, netns, flags)
> >> + * Decription
> >> + * Look for UDP socket matching 'tuple'. The return value must
> >> + * be checked, and if non-NULL, released via bpf_sk_release().
> >> + * @ctx: pointer to ctx
> >> + * @tuple: pointer to struct bpf_sock_tuple
> >> + * @tuple_size: size of the tuple
> >> + * @netns: network namespace id
> >> + * @flags: flags value
> >> + * Return
> >> + * pointer to socket ops on success, or
> >> + * NULL in case of failure
> >> + *
> >> + * int bpf_sk_release(sock, flags)
> >> + * Description
> >> + * Release the reference held by 'sock'.
> >> + * @sock: Pointer reference to release. Must be found via
> >> + * bpf_sk_lookup_xxx().
> >> + * @flags: flags value
> >> + * Return
> >> + * 0 on success, or a negative error in case of failure.
> >> */
^ permalink raw reply
* Re: [PATCHv2 bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
From: Joe Stringer @ 2018-09-24 18:04 UTC (permalink / raw)
To: daniel
Cc: Joe Stringer, ast, netdev, john fastabend, tgraf,
Martin KaFai Lau, Nitin Hande, mauricio.vasquez
In-Reply-To: <d2b803a4-509f-6d7f-1177-f3ccc1f875eb@iogearbox.net>
On Mon, 24 Sep 2018 at 05:12, Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> Hi Joe,
>
> couple of comments inline:
Thanks for the review, I'll fix up those bits.
> On 09/21/2018 07:10 PM, Joe Stringer wrote:
> > This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> > bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> > socket listening on this host, and returns a socket pointer which the
> > BPF program can then access to determine, for instance, whether to
> > forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> > socket, so when a BPF program makes use of this function, it must
> > subsequently pass the returned pointer into the newly added sk_release()
> > to return the reference.
> >
> > By way of example, the following pseudocode would filter inbound
> > connections at XDP if there is no corresponding service listening for
> > the traffic:
> >
> > struct bpf_sock_tuple tuple;
> > struct bpf_sock_ops *sk;
> >
> > populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> > sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> > if (!sk) {
> > // Couldn't find a socket listening for this traffic. Drop.
> > return TC_ACT_SHOT;
> > }
> > bpf_sk_release(sk, 0);
> > return TC_ACT_OK;
> >
> > Signed-off-by: Joe Stringer <joe@wand.net.nz>
> >
> > ---
> >
> > v2: Rework 'struct bpf_sock_tuple' to allow passing a packet pointer
> > Limit netns_id field to 32 bits
> > Fix compile error with CONFIG_IPV6 enabled
> > Allow direct packet access from helper
> > ---
> > include/uapi/linux/bpf.h | 57 ++++++++-
> > kernel/bpf/verifier.c | 8 +-
> > net/core/filter.c | 149 ++++++++++++++++++++++
> > tools/include/uapi/linux/bpf.h | 57 ++++++++-
> > tools/testing/selftests/bpf/bpf_helpers.h | 12 ++
> > 5 files changed, 280 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> > index aa5ccd2385ed..620adbb09a94 100644
> > --- a/include/uapi/linux/bpf.h
> > +++ b/include/uapi/linux/bpf.h
> > ...
> > +/* bpf_sk_lookup performs the core lookup for different types of sockets,
> > + * taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.
> > + * Returns the socket as an 'unsigned long' to simplify the casting in the
> > + * callers to satisfy BPF_CALL declarations.
> > + */
> > +static unsigned long
> > +bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
> > + u8 proto, u64 netns_id, u64 flags)
> > +{
> > + struct net *caller_net = dev_net(skb->dev);
>
> For sk_skb programs, are we *always* guaranteed to have a skb->dev assigned?
>
> This definitely holds true for tc programs, but afaik not for sk_skb ones where
> you enable the helpers below, so this would result in a NULL ptr dereference.
I'll update this to take the netns from the skb->sk in those hooks.
> > +BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
> > +{
> > + if (!sock_flag(sk, SOCK_RCU_FREE))
> > + sock_gen_put(sk);
> > +
> > + if (unlikely(flags))
> > + return -EINVAL;
>
> I guess it's probably okay to leave here, though I'm wondering whether it's
> worth to have a flags part in general in this helper. We need to release the
> reference in any case beforehands anyway as we otherwise leak it. Personally,
> I'd probably that arg here.
I agree, I can't think of a good reason to have optional behaviour on
socket release. I'll drop it.
> > + return 0;
> > +}
> > +
> > +static const struct bpf_func_proto bpf_sk_release_proto = {
> > + .func = bpf_sk_release,
> > + .gpl_only = false,
> > + .ret_type = RET_INTEGER,
> > + .arg1_type = ARG_PTR_TO_SOCKET,
> > + .arg2_type = ARG_ANYTHING,
> > +};
> > +
> > bool bpf_helper_changes_pkt_data(void *func)
> > {
> > if (func == bpf_skb_vlan_push ||
> > @@ -5018,6 +5155,12 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> > case BPF_FUNC_skb_ancestor_cgroup_id:
> > return &bpf_skb_ancestor_cgroup_id_proto;
> > #endif
> > + case BPF_FUNC_sk_lookup_tcp:
> > + return &bpf_sk_lookup_tcp_proto;
> > + case BPF_FUNC_sk_lookup_udp:
> > + return &bpf_sk_lookup_udp_proto;
> > + case BPF_FUNC_sk_release:
> > + return &bpf_sk_release_proto;
> > default:
> > return bpf_base_func_proto(func_id);
> > }
> > @@ -5118,6 +5261,12 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> > return &bpf_sk_redirect_hash_proto;
> > case BPF_FUNC_get_local_storage:
> > return &bpf_get_local_storage_proto;
> > + case BPF_FUNC_sk_lookup_tcp:
> > + return &bpf_sk_lookup_tcp_proto;
> > + case BPF_FUNC_sk_lookup_udp:
> > + return &bpf_sk_lookup_udp_proto;
> > + case BPF_FUNC_sk_release:
> > + return &bpf_sk_release_proto;
>
> (See comment above.)
^ permalink raw reply
* [PATCH RFC net-next] net: enable RPS on vlan devices
From: Shannon Nelson @ 2018-09-24 18:01 UTC (permalink / raw)
To: netdev; +Cc: silviu.smarandache
This patch modifies the RPS processing code so that it searches
for a matching vlan interface on the packet and then uses the
RPS settings of the vlan interface. If no vlan interface
is found or the vlan interface does not have RPS enabled,
it will fall back to the RPS settings of the underlying device.
In supporting VMs where we can't control the OS being used,
we'd like to separate the VM cpu processing from the host's
cpus as a way to help mitigate the impact of the L1TF issue.
When running the VM's traffic on a vlan we can stick the Rx
processing on one set of cpus separate from the VM's cpus.
Yes, choosing to use this may cause a bit of throughput pain
when the packets are actually passed into the VM and have to
move from one cache to another.
Orabug: 28645929
Signed-off-by: Silviu Smarandache <silviu.smarandache@oracle.com>
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
net/core/dev.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 56 insertions(+), 3 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 559a912..28b12d1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3735,8 +3735,8 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
* CPU from the RPS map of the receiving queue for a given skb.
* rcu_read_lock must be held on entry.
*/
-static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
- struct rps_dev_flow **rflowp)
+static int __get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
+ struct rps_dev_flow **rflowp)
{
const struct rps_sock_flow_table *sock_flow_table;
struct netdev_rx_queue *rxqueue = dev->_rx;
@@ -3830,6 +3830,35 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
return cpu;
}
+static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
+ struct rps_dev_flow **rflowp)
+{
+ /* Check for a vlan device with RPS settings */
+ if (skb_vlan_tag_present(skb)) {
+ struct net_device *vdev;
+ u16 vid;
+
+ vid = skb_vlan_tag_get_id(skb);
+ vdev = __vlan_find_dev_deep_rcu(dev, skb->vlan_proto, vid);
+ if (vdev) {
+ /* recorded queue is not referring to the vlan device.
+ * Save and restore it
+ */
+ int cpu;
+ u16 queue_mapping = skb_get_queue_mapping(skb);
+
+ skb_set_queue_mapping(skb, 0);
+ cpu = __get_rps_cpu(vdev, skb, rflowp);
+ skb_set_queue_mapping(skb, queue_mapping);
+ if (cpu != -1)
+ return cpu;
+ }
+ }
+
+ /* Fall back to RPS settings of original device */
+ return __get_rps_cpu(dev, skb, rflowp);
+}
+
#ifdef CONFIG_RFS_ACCEL
/**
@@ -4201,12 +4230,23 @@ static int netif_rx_internal(struct sk_buff *skb)
preempt_disable();
rcu_read_lock();
+ /* strip any vlan tag before calling get_rps_cpu() */
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
+ skb->protocol == cpu_to_be16(ETH_P_8021AD)) {
+ skb = skb_vlan_untag(skb);
+ if (unlikely(!skb)) {
+ ret = NET_RX_DROP;
+ goto unlock;
+ }
+ }
+
cpu = get_rps_cpu(skb->dev, skb, &rflow);
if (cpu < 0)
cpu = smp_processor_id();
ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
+unlock:
rcu_read_unlock();
preempt_enable();
} else
@@ -4755,8 +4795,19 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
#ifdef CONFIG_RPS
if (static_key_false(&rps_needed)) {
struct rps_dev_flow voidflow, *rflow = &voidflow;
- int cpu = get_rps_cpu(skb->dev, skb, &rflow);
+ int cpu;
+
+ /* strip any vlan tag before calling get_rps_cpu() */
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
+ skb->protocol == cpu_to_be16(ETH_P_8021AD)) {
+ skb = skb_vlan_untag(skb);
+ if (unlikely(!skb)) {
+ ret = NET_RX_DROP;
+ goto out;
+ }
+ }
+ cpu = get_rps_cpu(skb->dev, skb, &rflow);
if (cpu >= 0) {
ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
rcu_read_unlock();
@@ -4765,6 +4816,8 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
}
#endif
ret = __netif_receive_skb(skb);
+
+out:
rcu_read_unlock();
return ret;
}
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] net: nixge: Address compiler warnings when building for i386
From: Andrew Lunn @ 2018-09-25 0:00 UTC (permalink / raw)
To: Moritz Fischer
Cc: linux-kernel, netdev, keescook, davem, moritz.fischer, f.fainelli,
alex.williams
In-Reply-To: <20180924212712.1790-1-mdf@kernel.org>
On Mon, Sep 24, 2018 at 02:27:12PM -0700, Moritz Fischer wrote:
> Address compiler warnings reported by kbuild autobuilders
> when building for i386 as a result of dma_addr_t size on
> different architectures.
>
> warning: cast to pointer from integer of different size
> [-Wint-to-pointer-cast]
>
> Signed-off-by: Moritz Fischer <mdf@kernel.org>
> ---
> drivers/net/ethernet/ni/nixge.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
> index 74cf52e3fb09..0611f2335b4a 100644
> --- a/drivers/net/ethernet/ni/nixge.c
> +++ b/drivers/net/ethernet/ni/nixge.c
> @@ -127,8 +127,8 @@ struct nixge_hw_dma_bd {
> #ifdef CONFIG_PHYS_ADDR_T_64BIT
> #define nixge_hw_dma_bd_set_addr(bd, field, addr) \
> do { \
> - (bd)->field##_lo = lower_32_bits(((u64)addr)); \
> - (bd)->field##_hi = upper_32_bits(((u64)addr)); \
> + (bd)->field##_lo = lower_32_bits((addr)); \
> + (bd)->field##_hi = upper_32_bits((addr)); \
> } while (0)
Hi Maritz
Maybe turn this into an function. It is small enough it will get
inlined. You then gain type checking. Make addr a void *.
> #else
> #define nixge_hw_dma_bd_set_addr(bd, field, addr) \
> @@ -251,7 +251,7 @@ static void nixge_hw_dma_bd_release(struct net_device *ndev)
> NIXGE_MAX_JUMBO_FRAME_SIZE,
> DMA_FROM_DEVICE);
>
> - skb = (struct sk_buff *)
> + skb = (struct sk_buff *)(uintptr_t)
> nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i],
> sw_id_offset);
How about making nixge_hw_dma_bd_get_addr return a void *. You can
assign that to anything without needing a cast.
Andrew
^ permalink raw reply
* Re: Documentation: Add HOWTO Korean translation into BPF and XDP Reference Guide.
From: Tejun Heo @ 2018-09-24 17:15 UTC (permalink / raw)
To: Changan Song; +Cc: netdev, Alexei Starovoitov, Song Liu
In-Reply-To: <20180921042238.19582-1-csongxdp@gmail.com>
Hello,
First of all, thanks a lot for the contribution. It'd be great to
have a korean translation. I glanced over it and there often were
areas where it was a bit challenging to understand without going back
to the english version.
I think this would still be helpful and a step in the right direction;
however, I think it'd be helpful to explicitly note, in korean, that
the translation is still work-in-progress and the readers are
recommended to refer back to the english copy when there's any doubt.
Thanks.
--
tejun
^ permalink raw reply
* Re: pull-request: bpf 2018-09-24
From: David Miller @ 2018-09-24 17:09 UTC (permalink / raw)
To: daniel; +Cc: ast, netdev
In-Reply-To: <20180924093100.5878-1-daniel@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Mon, 24 Sep 2018 11:31:00 +0200
> The following pull-request contains BPF updates for your *net* tree.
>
> The main changes are:
>
> 1) Several fixes for BPF sockmap to only allow sockets being attached in
> ESTABLISHED state, from John.
>
> 2) Fix up the license to LGPL/BSD for the libc compat header which contains
> fallback helpers that libbpf and bpftool is using, from Jakub.
>
> Please consider pulling these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
Series applied, thanks Daniel.
^ permalink raw reply
* Re: Ping: [PATCH 0/3] xen-netback: hash mapping hanling adjustments
From: David Miller @ 2018-09-24 16:49 UTC (permalink / raw)
To: JBeulich; +Cc: paul.durrant, wei.liu2, xen-devel, netdev
In-Reply-To: <5BA895B602000078001EB059@prv1-mh.provo.novell.com>
From: "Jan Beulich" <JBeulich@suse.com>
Date: Mon, 24 Sep 2018 01:43:50 -0600
>>>> On 11.09.18 at 12:16, <wei.liu2@citrix.com> wrote:
>> On Tue, Sep 11, 2018 at 02:12:07AM -0600, Jan Beulich wrote:
>>> >>> On 28.08.18 at 16:54, wrote:
>>> > First and foremost the fix for XSA-270. On top of that further changes
>>> > which looked desirable to me while investigating that XSA.
>>> >
>>> > 1: fix input validation in xenvif_set_hash_mapping()
>>> > 2: validate queue numbers in xenvif_set_hash_mapping()
>>> > 3: handle page straddling in xenvif_set_hash_mapping()
>>> >
>>> > Signed-off-by: Jan Beulich <jbeulich@suse.com>
>>>
>>> What is the way forward here? I've got R-b-s from Paul for all three
>>> patches, and a minor change request on patch 2 from Wei. I'm not
>>> really certain what to do in this case (hints appreciated), but could
>>> at least the security fix (patch 1) be applied immediately?
>>
>> If you happen to resend, please make the adjustment; otherwise I'm fine
>> with the patches as they are. I don't want to block useful things on
>> cosmetic issues.
>
> Dave? I notice none of the patches is in 4.19-rc5, not even the security
> fix, the advisory for which had gone public over a month ago.
If it's not in my patchwork queue, you have to resend the series and
make it clear that it should be applied to the networking tree by
putting "[PATCH net N/M]" in the Subject lines.
Thank you.
^ permalink raw reply
* Re: [PATCH v2 net-next 0/9] bnxt_en: devlink param updates
From: Jakub Kicinski @ 2018-09-24 16:39 UTC (permalink / raw)
To: Vasundhara Volam; +Cc: davem, michael.chan, netdev
In-Reply-To: <1537766181-18994-1-git-send-email-vasundhara-v.volam@broadcom.com>
On Mon, 24 Sep 2018 10:46:12 +0530, Vasundhara Volam wrote:
> This patchset adds support for 3 generic and 1 driver-specific devlink
> parameters. Add documentation for these configuration parameters.
>
> Also, this patchset adds support to return proper error code if
> HWRM_NVM_GET/SET_VARIABLE commands return error code
> HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED.
>
> v1->v2:
> -Remove hw_tc_offload parameter.
> -Update all patches with Cc of MAINTAINERS.
> -Add more description in commit message for device specific parameter.
> -Add a new Documentation/networking/devlink-params.txt with some
> generic devlink parameters information.
> -Add a new Documentation/networking/devlink-params-bnxt_en.txt with devlink
> parameters information that are supported by bnxt_en driver.
>
> Vasundhara Volam (9):
> devlink: Add generic parameter ignore_ari
> devlink: Add generic parameter msix_vec_per_pf_max
> devlink: Add generic parameter msix_vec_per_pf_min
Nobody agreed with me that we need structure the PCIe bits better so
I'll let go...
> bnxt_en: Use ignore_ari devlink parameter
> bnxt_en: return proper error when FW returns
> HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED
> bnxt_en: Use msix_vec_per_pf_max and msix_vec_per_pf_min devlink
> params.
> bnxt_en: Add a driver specific gre_ver_check devlink parameter.
This looks like configuring forwarding rules with devlink, but again,
I won't object if I'm the only one who finds this inappropriate.
You should CC people who gave you feedback on the previous version.
> devlink: Add Documentation/networking/devlink-params.txt
> devlink: Add Documentation/networking/devlink-params-bnxt.txt
^ permalink raw reply
* [PATCH 5/5] ixgbe: add AF_XDP zero-copy Tx support
From: Björn Töpel @ 2018-09-24 16:35 UTC (permalink / raw)
To: jeffrey.t.kirsher, intel-wired-lan
Cc: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
daniel, netdev, brouer, u9012063, tuc
In-Reply-To: <20180924163557.1187-1-bjorn.topel@gmail.com>
From: Björn Töpel <bjorn.topel@intel.com>
This patch adds zero-copy Tx support for AF_XDP sockets. It implements
the ndo_xsk_async_xmit netdev ndo and performs all the Tx logic from a
NAPI context. This means pulling egress packets from the Tx ring,
placing the frames on the NIC HW descriptor ring and completing sent
frames back to the application via the completion ring.
The regular XDP Tx ring is used for AF_XDP as well. This rationale for
this is as follows: XDP_REDIRECT guarantees mutual exclusion between
different NAPI contexts based on CPU id. In other words, a netdev can
XDP_REDIRECT to another netdev with a different NAPI context, since
the operation is bound to a specific core and each core has its own
hardware ring.
As the AF_XDP Tx action is running in the same NAPI context and using
the same ring, it will also be protected from XDP_REDIRECT actions
with the exact same mechanism.
As with AF_XDP Rx, all AF_XDP Tx specific functions are added to
ixgbe_xsk.c.
Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 16 +-
.../ethernet/intel/ixgbe/ixgbe_txrx_common.h | 4 +
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 175 ++++++++++++++++++
3 files changed, 194 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 4e9b28894a5b..64b19346396d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3161,7 +3161,11 @@ int ixgbe_poll(struct napi_struct *napi, int budget)
#endif
ixgbe_for_each_ring(ring, q_vector->tx) {
- if (!ixgbe_clean_tx_irq(q_vector, ring, budget))
+ bool wd = ring->xsk_umem ?
+ ixgbe_clean_xdp_tx_irq(q_vector, ring, budget) :
+ ixgbe_clean_tx_irq(q_vector, ring, budget);
+
+ if (!wd)
clean_complete = false;
}
@@ -3472,6 +3476,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
u32 txdctl = IXGBE_TXDCTL_ENABLE;
u8 reg_idx = ring->reg_idx;
+ if (ring_is_xdp(ring))
+ ring->xsk_umem = ixgbe_xsk_umem(adapter, ring);
+
/* disable queue to avoid issues while updating state */
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), 0);
IXGBE_WRITE_FLUSH(hw);
@@ -5938,6 +5945,11 @@ static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring)
u16 i = tx_ring->next_to_clean;
struct ixgbe_tx_buffer *tx_buffer = &tx_ring->tx_buffer_info[i];
+ if (tx_ring->xsk_umem) {
+ ixgbe_xsk_clean_tx_ring(tx_ring);
+ goto out;
+ }
+
while (i != tx_ring->next_to_use) {
union ixgbe_adv_tx_desc *eop_desc, *tx_desc;
@@ -5989,6 +6001,7 @@ static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring)
if (!ring_is_xdp(tx_ring))
netdev_tx_reset_queue(txring_txq(tx_ring));
+out:
/* reset next_to_use and next_to_clean */
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
@@ -10369,6 +10382,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_features_check = ixgbe_features_check,
.ndo_bpf = ixgbe_xdp,
.ndo_xdp_xmit = ixgbe_xdp_xmit,
+ .ndo_xsk_async_xmit = ixgbe_xsk_async_xmit,
};
static void ixgbe_disable_txr_hw(struct ixgbe_adapter *adapter,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
index 56afb685c648..53d4089f5644 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
@@ -42,5 +42,9 @@ int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
const int budget);
void ixgbe_xsk_clean_rx_ring(struct ixgbe_ring *rx_ring);
+bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
+ struct ixgbe_ring *tx_ring, int napi_budget);
+int ixgbe_xsk_async_xmit(struct net_device *dev, u32 queue_id);
+void ixgbe_xsk_clean_tx_ring(struct ixgbe_ring *tx_ring);
#endif /* #define _IXGBE_TXRX_COMMON_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
index 253ce3cfbcf1..e998ed880460 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -637,3 +637,178 @@ void ixgbe_xsk_clean_rx_ring(struct ixgbe_ring *rx_ring)
}
}
}
+
+static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget)
+{
+ union ixgbe_adv_tx_desc *tx_desc = NULL;
+ struct ixgbe_tx_buffer *tx_bi;
+ bool work_done = true;
+ u32 len, cmd_type;
+ dma_addr_t dma;
+
+ while (budget-- > 0) {
+ if (unlikely(!ixgbe_desc_unused(xdp_ring))) {
+ work_done = false;
+ break;
+ }
+
+ if (!xsk_umem_consume_tx(xdp_ring->xsk_umem, &dma, &len))
+ break;
+
+ dma_sync_single_for_device(xdp_ring->dev, dma, len,
+ DMA_BIDIRECTIONAL);
+
+ tx_bi = &xdp_ring->tx_buffer_info[xdp_ring->next_to_use];
+ tx_bi->bytecount = len;
+ tx_bi->xdpf = NULL;
+
+ tx_desc = IXGBE_TX_DESC(xdp_ring, xdp_ring->next_to_use);
+ tx_desc->read.buffer_addr = cpu_to_le64(dma);
+
+ /* put descriptor type bits */
+ cmd_type = IXGBE_ADVTXD_DTYP_DATA |
+ IXGBE_ADVTXD_DCMD_DEXT |
+ IXGBE_ADVTXD_DCMD_IFCS;
+ cmd_type |= len | IXGBE_TXD_CMD;
+ tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
+ tx_desc->read.olinfo_status =
+ cpu_to_le32(len << IXGBE_ADVTXD_PAYLEN_SHIFT);
+
+ xdp_ring->next_to_use++;
+ if (xdp_ring->next_to_use == xdp_ring->count)
+ xdp_ring->next_to_use = 0;
+ }
+
+ if (tx_desc) {
+ ixgbe_xdp_ring_update_tail(xdp_ring);
+ xsk_umem_consume_tx_done(xdp_ring->xsk_umem);
+ }
+
+ return !!budget && work_done;
+}
+
+static void ixgbe_clean_xdp_tx_buffer(struct ixgbe_ring *tx_ring,
+ struct ixgbe_tx_buffer *tx_bi)
+{
+ xdp_return_frame(tx_bi->xdpf);
+ dma_unmap_single(tx_ring->dev,
+ dma_unmap_addr(tx_bi, dma),
+ dma_unmap_len(tx_bi, len), DMA_TO_DEVICE);
+ dma_unmap_len_set(tx_bi, len, 0);
+}
+
+bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
+ struct ixgbe_ring *tx_ring, int napi_budget)
+{
+ unsigned int total_packets = 0, total_bytes = 0;
+ u32 i = tx_ring->next_to_clean, xsk_frames = 0;
+ unsigned int budget = q_vector->tx.work_limit;
+ struct xdp_umem *umem = tx_ring->xsk_umem;
+ union ixgbe_adv_tx_desc *tx_desc;
+ struct ixgbe_tx_buffer *tx_bi;
+ bool xmit_done;
+
+ tx_bi = &tx_ring->tx_buffer_info[i];
+ tx_desc = IXGBE_TX_DESC(tx_ring, i);
+ i -= tx_ring->count;
+
+ do {
+ if (!(tx_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)))
+ break;
+
+ total_bytes += tx_bi->bytecount;
+ total_packets += tx_bi->gso_segs;
+
+ if (tx_bi->xdpf)
+ ixgbe_clean_xdp_tx_buffer(tx_ring, tx_bi);
+ else
+ xsk_frames++;
+
+ tx_bi->xdpf = NULL;
+ total_bytes += tx_bi->bytecount;
+
+ tx_bi++;
+ tx_desc++;
+ i++;
+ if (unlikely(!i)) {
+ i -= tx_ring->count;
+ tx_bi = tx_ring->tx_buffer_info;
+ tx_desc = IXGBE_TX_DESC(tx_ring, 0);
+ }
+
+ /* issue prefetch for next Tx descriptor */
+ prefetch(tx_desc);
+
+ /* update budget accounting */
+ budget--;
+ } while (likely(budget));
+
+ i += tx_ring->count;
+ tx_ring->next_to_clean = i;
+
+ u64_stats_update_begin(&tx_ring->syncp);
+ tx_ring->stats.bytes += total_bytes;
+ tx_ring->stats.packets += total_packets;
+ u64_stats_update_end(&tx_ring->syncp);
+ q_vector->tx.total_bytes += total_bytes;
+ q_vector->tx.total_packets += total_packets;
+
+ if (xsk_frames)
+ xsk_umem_complete_tx(umem, xsk_frames);
+
+ xmit_done = ixgbe_xmit_zc(tx_ring, q_vector->tx.work_limit);
+ return budget > 0 && xmit_done;
+}
+
+int ixgbe_xsk_async_xmit(struct net_device *dev, u32 queue_id)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ struct ixgbe_ring *ring;
+
+ if (test_bit(__IXGBE_DOWN, &adapter->state))
+ return -ENETDOWN;
+
+ if (!READ_ONCE(adapter->xdp_prog))
+ return -ENXIO;
+
+ if (queue_id >= adapter->num_rx_queues)
+ return -ENXIO;
+
+ if (!adapter->xsk_umems[queue_id])
+ return -ENXIO;
+
+ ring = adapter->xdp_ring[queue_id];
+ if (!napi_if_scheduled_mark_missed(&ring->q_vector->napi)) {
+ u64 eics = BIT_ULL(ring->q_vector->v_idx);
+
+ ixgbe_irq_rearm_queues(adapter, eics);
+ }
+
+ return 0;
+}
+
+void ixgbe_xsk_clean_tx_ring(struct ixgbe_ring *tx_ring)
+{
+ u16 ntc = tx_ring->next_to_clean, ntu = tx_ring->next_to_use;
+ struct xdp_umem *umem = tx_ring->xsk_umem;
+ struct ixgbe_tx_buffer *tx_bi;
+ u32 xsk_frames = 0;
+
+ while (ntc != ntu) {
+ tx_bi = &tx_ring->tx_buffer_info[ntc];
+
+ if (tx_bi->xdpf)
+ ixgbe_clean_xdp_tx_buffer(tx_ring, tx_bi);
+ else
+ xsk_frames++;
+
+ tx_bi->xdpf = NULL;
+
+ ntc++;
+ if (ntc == tx_ring->count)
+ ntc = 0;
+ }
+
+ if (xsk_frames)
+ xsk_umem_complete_tx(umem, xsk_frames);
+}
--
2.17.1
^ permalink raw reply related
* [PATCH 4/5] ixgbe: move common Tx functions to ixgbe_txrx_common.h
From: Björn Töpel @ 2018-09-24 16:35 UTC (permalink / raw)
To: jeffrey.t.kirsher, intel-wired-lan
Cc: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
daniel, netdev, brouer, u9012063, tuc
In-Reply-To: <20180924163557.1187-1-bjorn.topel@gmail.com>
From: Björn Töpel <bjorn.topel@intel.com>
This patch prepares for the upcoming zero-copy Tx functionality by
moving common functions used both by the regular path and zero-copy
path.
Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 9 +++------
drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h | 5 +++++
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 4e6726c623a8..4e9b28894a5b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -895,8 +895,8 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
}
}
-static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
- u64 qmask)
+void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
+ u64 qmask)
{
u32 mask;
@@ -8150,9 +8150,6 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
return __ixgbe_maybe_stop_tx(tx_ring, size);
}
-#define IXGBE_TXD_CMD (IXGBE_TXD_CMD_EOP | \
- IXGBE_TXD_CMD_RS)
-
static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
struct ixgbe_tx_buffer *first,
const u8 hdr_len)
@@ -10275,7 +10272,7 @@ static int ixgbe_xdp(struct net_device *dev, struct netdev_bpf *xdp)
}
}
-static void ixgbe_xdp_ring_update_tail(struct ixgbe_ring *ring)
+void ixgbe_xdp_ring_update_tail(struct ixgbe_ring *ring)
{
/* Force memory writes to complete before letting h/w know there
* are new descriptors to fetch.
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
index cf219f4e009d..56afb685c648 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
@@ -9,6 +9,9 @@
#define IXGBE_XDP_TX BIT(1)
#define IXGBE_XDP_REDIR BIT(2)
+#define IXGBE_TXD_CMD (IXGBE_TXD_CMD_EOP | \
+ IXGBE_TXD_CMD_RS)
+
int ixgbe_xmit_xdp_ring(struct ixgbe_adapter *adapter,
struct xdp_frame *xdpf);
bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring,
@@ -19,6 +22,8 @@ void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
struct sk_buff *skb);
void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector,
struct sk_buff *skb);
+void ixgbe_xdp_ring_update_tail(struct ixgbe_ring *ring);
+void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, u64 qmask);
void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring);
void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring);
--
2.17.1
^ permalink raw reply related
* [PATCH 3/5] ixgbe: add AF_XDP zero-copy Rx support
From: Björn Töpel @ 2018-09-24 16:35 UTC (permalink / raw)
To: jeffrey.t.kirsher, intel-wired-lan
Cc: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
daniel, netdev, brouer, u9012063, tuc
In-Reply-To: <20180924163557.1187-1-bjorn.topel@gmail.com>
From: Björn Töpel <bjorn.topel@intel.com>
This patch adds zero-copy Rx support for AF_XDP sockets. Instead of
allocating buffers of type MEM_TYPE_PAGE_SHARED, the Rx frames are
allocated as MEM_TYPE_ZERO_COPY when AF_XDP is enabled for a certain
queue.
All AF_XDP specific functions are added to a new file, ixgbe_xsk.c.
Note that when AF_XDP zero-copy is enabled, the XDP action XDP_PASS
will allocate a new buffer and copy the zero-copy frame prior passing
it to the kernel stack.
Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
---
drivers/net/ethernet/intel/ixgbe/Makefile | 3 +-
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 26 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 78 ++-
.../ethernet/intel/ixgbe/ixgbe_txrx_common.h | 15 +
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 639 ++++++++++++++++++
5 files changed, 741 insertions(+), 20 deletions(-)
create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile
index 5414685189ce..ca6b0c458e4a 100644
--- a/drivers/net/ethernet/intel/ixgbe/Makefile
+++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -8,7 +8,8 @@ obj-$(CONFIG_IXGBE) += ixgbe.o
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
- ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o
+ ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o \
+ ixgbe_xsk.o
ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
ixgbe_dcb_82599.o ixgbe_dcb_nl.o
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 265db172042a..421fdac3a76d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -228,13 +228,17 @@ struct ixgbe_tx_buffer {
struct ixgbe_rx_buffer {
struct sk_buff *skb;
dma_addr_t dma;
- struct page *page;
-#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
- __u32 page_offset;
-#else
- __u16 page_offset;
-#endif
- __u16 pagecnt_bias;
+ union {
+ struct {
+ struct page *page;
+ __u32 page_offset;
+ __u16 pagecnt_bias;
+ };
+ struct {
+ void *addr;
+ u64 handle;
+ };
+ };
};
struct ixgbe_queue_stats {
@@ -348,6 +352,9 @@ struct ixgbe_ring {
struct ixgbe_rx_queue_stats rx_stats;
};
struct xdp_rxq_info xdp_rxq;
+ struct xdp_umem *xsk_umem;
+ struct zero_copy_allocator zca; /* ZC allocator anchor */
+ u16 rx_buf_len;
} ____cacheline_internodealigned_in_smp;
enum ixgbe_ring_f_enum {
@@ -765,6 +772,11 @@ struct ixgbe_adapter {
#ifdef CONFIG_XFRM_OFFLOAD
struct ixgbe_ipsec *ipsec;
#endif /* CONFIG_XFRM_OFFLOAD */
+
+ /* AF_XDP zero-copy */
+ struct xdp_umem **xsk_umems;
+ u16 num_xsk_umems_used;
+ u16 num_xsk_umems;
};
static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3e2e6fb2215a..4e6726c623a8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -34,6 +34,7 @@
#include <net/tc_act/tc_mirred.h>
#include <net/vxlan.h>
#include <net/mpls.h>
+#include <net/xdp_sock.h>
#include "ixgbe.h"
#include "ixgbe_common.h"
@@ -3176,7 +3177,10 @@ int ixgbe_poll(struct napi_struct *napi, int budget)
per_ring_budget = budget;
ixgbe_for_each_ring(ring, q_vector->rx) {
- int cleaned = ixgbe_clean_rx_irq(q_vector, ring,
+ int cleaned = ring->xsk_umem ?
+ ixgbe_clean_rx_irq_zc(q_vector, ring,
+ per_ring_budget) :
+ ixgbe_clean_rx_irq(q_vector, ring,
per_ring_budget);
work_done += cleaned;
@@ -3706,10 +3710,27 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
srrctl = IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT;
/* configure the packet buffer length */
- if (test_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state))
+ if (rx_ring->xsk_umem) {
+ u32 xsk_buf_len = rx_ring->xsk_umem->chunk_size_nohr -
+ XDP_PACKET_HEADROOM;
+
+ /* If the MAC support setting RXDCTL.RLPML, the
+ * SRRCTL[n].BSIZEPKT is set to PAGE_SIZE and
+ * RXDCTL.RLPML is set to the actual UMEM buffer
+ * size. If not, then we are stuck with a 1k buffer
+ * size resolution. In this case frames larger than
+ * the UMEM buffer size viewed in a 1k resolution will
+ * be dropped.
+ */
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ srrctl |= PAGE_SIZE >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ else
+ srrctl |= xsk_buf_len >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ } else if (test_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state)) {
srrctl |= IXGBE_RXBUFFER_3K >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- else
+ } else {
srrctl |= IXGBE_RXBUFFER_2K >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ }
/* configure descriptor type */
srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
@@ -4032,6 +4053,19 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
u32 rxdctl;
u8 reg_idx = ring->reg_idx;
+ xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
+ ring->xsk_umem = ixgbe_xsk_umem(adapter, ring);
+ if (ring->xsk_umem) {
+ ring->zca.free = ixgbe_zca_free;
+ WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
+ MEM_TYPE_ZERO_COPY,
+ &ring->zca));
+
+ } else {
+ WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
+ MEM_TYPE_PAGE_SHARED, NULL));
+ }
+
/* disable queue to avoid use of these values while updating state */
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
rxdctl &= ~IXGBE_RXDCTL_ENABLE;
@@ -4081,6 +4115,17 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
#endif
}
+ if (ring->xsk_umem && hw->mac.type != ixgbe_mac_82599EB) {
+ u32 xsk_buf_len = ring->xsk_umem->chunk_size_nohr -
+ XDP_PACKET_HEADROOM;
+
+ rxdctl &= ~(IXGBE_RXDCTL_RLPMLMASK |
+ IXGBE_RXDCTL_RLPML_EN);
+ rxdctl |= xsk_buf_len | IXGBE_RXDCTL_RLPML_EN;
+
+ ring->rx_buf_len = xsk_buf_len;
+ }
+
/* initialize rx_buffer_info */
memset(ring->rx_buffer_info, 0,
sizeof(struct ixgbe_rx_buffer) * ring->count);
@@ -4094,7 +4139,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
- ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
+ if (ring->xsk_umem)
+ ixgbe_alloc_rx_buffers_zc(ring, ixgbe_desc_unused(ring));
+ else
+ ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
}
static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter)
@@ -5202,6 +5250,11 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
u16 i = rx_ring->next_to_clean;
struct ixgbe_rx_buffer *rx_buffer = &rx_ring->rx_buffer_info[i];
+ if (rx_ring->xsk_umem) {
+ ixgbe_xsk_clean_rx_ring(rx_ring);
+ goto skip_free;
+ }
+
/* Free all the Rx ring sk_buffs */
while (i != rx_ring->next_to_alloc) {
if (rx_buffer->skb) {
@@ -5240,6 +5293,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
}
}
+skip_free:
rx_ring->next_to_alloc = 0;
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
@@ -6435,7 +6489,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
struct device *dev = rx_ring->dev;
int orig_node = dev_to_node(dev);
int ring_node = -1;
- int size, err;
+ int size;
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
@@ -6472,13 +6526,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
rx_ring->queue_index) < 0)
goto err;
- err = xdp_rxq_info_reg_mem_model(&rx_ring->xdp_rxq,
- MEM_TYPE_PAGE_SHARED, NULL);
- if (err) {
- xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
- goto err;
- }
-
rx_ring->xdp_prog = adapter->xdp_prog;
return 0;
@@ -10216,6 +10263,13 @@ static int ixgbe_xdp(struct net_device *dev, struct netdev_bpf *xdp)
xdp->prog_id = adapter->xdp_prog ?
adapter->xdp_prog->aux->id : 0;
return 0;
+ case XDP_QUERY_XSK_UMEM:
+ return ixgbe_xsk_umem_query(adapter, &xdp->xsk.umem,
+ xdp->xsk.queue_id);
+ case XDP_SETUP_XSK_UMEM:
+ return ixgbe_xsk_umem_setup(adapter, xdp->xsk.umem,
+ xdp->xsk.queue_id);
+
default:
return -EINVAL;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
index 3780d315b991..cf219f4e009d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
@@ -23,4 +23,19 @@ void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector,
void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring);
void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring);
+struct xdp_umem *ixgbe_xsk_umem(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring);
+int ixgbe_xsk_umem_query(struct ixgbe_adapter *adapter, struct xdp_umem **umem,
+ u16 qid);
+int ixgbe_xsk_umem_setup(struct ixgbe_adapter *adapter, struct xdp_umem *umem,
+ u16 qid);
+
+void ixgbe_zca_free(struct zero_copy_allocator *alloc, unsigned long handle);
+
+void ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 cleaned_count);
+int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector,
+ struct ixgbe_ring *rx_ring,
+ const int budget);
+void ixgbe_xsk_clean_rx_ring(struct ixgbe_ring *rx_ring);
+
#endif /* #define _IXGBE_TXRX_COMMON_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
new file mode 100644
index 000000000000..253ce3cfbcf1
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -0,0 +1,639 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018 Intel Corporation. */
+
+#include <linux/bpf_trace.h>
+#include <net/xdp_sock.h>
+#include <net/xdp.h>
+
+#include "ixgbe.h"
+#include "ixgbe_txrx_common.h"
+
+struct xdp_umem *ixgbe_xsk_umem(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ bool xdp_on = READ_ONCE(adapter->xdp_prog);
+ int qid = ring->queue_index;
+
+ if (!adapter->xsk_umems || !adapter->xsk_umems[qid] || !xdp_on)
+ return NULL;
+
+ return adapter->xsk_umems[qid];
+}
+
+static int ixgbe_alloc_xsk_umems(struct ixgbe_adapter *adapter)
+{
+ if (adapter->xsk_umems)
+ return 0;
+
+ adapter->num_xsk_umems_used = 0;
+ adapter->num_xsk_umems = adapter->num_rx_queues;
+ adapter->xsk_umems = kcalloc(adapter->num_xsk_umems,
+ sizeof(*adapter->xsk_umems),
+ GFP_KERNEL);
+ if (!adapter->xsk_umems) {
+ adapter->num_xsk_umems = 0;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int ixgbe_add_xsk_umem(struct ixgbe_adapter *adapter,
+ struct xdp_umem *umem,
+ u16 qid)
+{
+ int err;
+
+ err = ixgbe_alloc_xsk_umems(adapter);
+ if (err)
+ return err;
+
+ adapter->xsk_umems[qid] = umem;
+ adapter->num_xsk_umems_used++;
+
+ return 0;
+}
+
+static void ixgbe_remove_xsk_umem(struct ixgbe_adapter *adapter, u16 qid)
+{
+ adapter->xsk_umems[qid] = NULL;
+ adapter->num_xsk_umems_used--;
+
+ if (adapter->num_xsk_umems == 0) {
+ kfree(adapter->xsk_umems);
+ adapter->xsk_umems = NULL;
+ adapter->num_xsk_umems = 0;
+ }
+}
+
+static int ixgbe_xsk_umem_dma_map(struct ixgbe_adapter *adapter,
+ struct xdp_umem *umem)
+{
+ struct device *dev = &adapter->pdev->dev;
+ unsigned int i, j;
+ dma_addr_t dma;
+
+ for (i = 0; i < umem->npgs; i++) {
+ dma = dma_map_page_attrs(dev, umem->pgs[i], 0, PAGE_SIZE,
+ DMA_BIDIRECTIONAL, IXGBE_RX_DMA_ATTR);
+ if (dma_mapping_error(dev, dma))
+ goto out_unmap;
+
+ umem->pages[i].dma = dma;
+ }
+
+ return 0;
+
+out_unmap:
+ for (j = 0; j < i; j++) {
+ dma_unmap_page_attrs(dev, umem->pages[i].dma, PAGE_SIZE,
+ DMA_BIDIRECTIONAL, IXGBE_RX_DMA_ATTR);
+ umem->pages[i].dma = 0;
+ }
+
+ return -1;
+}
+
+static void ixgbe_xsk_umem_dma_unmap(struct ixgbe_adapter *adapter,
+ struct xdp_umem *umem)
+{
+ struct device *dev = &adapter->pdev->dev;
+ unsigned int i;
+
+ for (i = 0; i < umem->npgs; i++) {
+ dma_unmap_page_attrs(dev, umem->pages[i].dma, PAGE_SIZE,
+ DMA_BIDIRECTIONAL, IXGBE_RX_DMA_ATTR);
+
+ umem->pages[i].dma = 0;
+ }
+}
+
+static int ixgbe_xsk_umem_enable(struct ixgbe_adapter *adapter,
+ struct xdp_umem *umem,
+ u16 qid)
+{
+ struct xdp_umem_fq_reuse *reuseq;
+ bool if_running;
+ int err;
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+ return -EINVAL;
+
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+ return -EINVAL;
+
+ if (qid >= adapter->num_rx_queues)
+ return -EINVAL;
+
+ if (adapter->xsk_umems) {
+ if (qid >= adapter->num_xsk_umems)
+ return -EINVAL;
+ if (adapter->xsk_umems[qid])
+ return -EBUSY;
+ }
+
+ reuseq = xsk_reuseq_prepare(adapter->rx_ring[0]->count);
+ if (!reuseq)
+ return -ENOMEM;
+
+ xsk_reuseq_free(xsk_reuseq_swap(umem, reuseq));
+
+ err = ixgbe_xsk_umem_dma_map(adapter, umem);
+ if (err)
+ return err;
+
+ if_running = netif_running(adapter->netdev) &&
+ READ_ONCE(adapter->xdp_prog);
+
+ if (if_running)
+ ixgbe_txrx_ring_disable(adapter, qid);
+
+ err = ixgbe_add_xsk_umem(adapter, umem, qid);
+
+ if (if_running)
+ ixgbe_txrx_ring_enable(adapter, qid);
+
+ return err;
+}
+
+static int ixgbe_xsk_umem_disable(struct ixgbe_adapter *adapter, u16 qid)
+{
+ bool if_running;
+
+ if (!adapter->xsk_umems || qid >= adapter->num_xsk_umems ||
+ !adapter->xsk_umems[qid])
+ return -EINVAL;
+
+ if_running = netif_running(adapter->netdev) &&
+ READ_ONCE(adapter->xdp_prog);
+
+ if (if_running)
+ ixgbe_txrx_ring_disable(adapter, qid);
+
+ ixgbe_xsk_umem_dma_unmap(adapter, adapter->xsk_umems[qid]);
+ ixgbe_remove_xsk_umem(adapter, qid);
+
+ if (if_running)
+ ixgbe_txrx_ring_enable(adapter, qid);
+
+ return 0;
+}
+
+int ixgbe_xsk_umem_query(struct ixgbe_adapter *adapter, struct xdp_umem **umem,
+ u16 qid)
+{
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+ return -EINVAL;
+
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+ return -EINVAL;
+
+ if (qid >= adapter->num_rx_queues)
+ return -EINVAL;
+
+ if (adapter->xsk_umems) {
+ if (qid >= adapter->num_xsk_umems)
+ return -EINVAL;
+ *umem = adapter->xsk_umems[qid];
+ return 0;
+ }
+
+ *umem = NULL;
+ return 0;
+}
+
+int ixgbe_xsk_umem_setup(struct ixgbe_adapter *adapter, struct xdp_umem *umem,
+ u16 qid)
+{
+ return umem ? ixgbe_xsk_umem_enable(adapter, umem, qid) :
+ ixgbe_xsk_umem_disable(adapter, qid);
+}
+
+static int ixgbe_run_xdp_zc(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring,
+ struct xdp_buff *xdp)
+{
+ int err, result = IXGBE_XDP_PASS;
+ struct bpf_prog *xdp_prog;
+ struct xdp_frame *xdpf;
+ u32 act;
+
+ rcu_read_lock();
+ xdp_prog = READ_ONCE(rx_ring->xdp_prog);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
+ xdp->handle += xdp->data - xdp->data_hard_start;
+ switch (act) {
+ case XDP_PASS:
+ break;
+ case XDP_TX:
+ xdpf = convert_to_xdp_frame(xdp);
+ if (unlikely(!xdpf)) {
+ result = IXGBE_XDP_CONSUMED;
+ break;
+ }
+ result = ixgbe_xmit_xdp_ring(adapter, xdpf);
+ break;
+ case XDP_REDIRECT:
+ err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
+ result = !err ? IXGBE_XDP_REDIR : IXGBE_XDP_CONSUMED;
+ break;
+ default:
+ bpf_warn_invalid_xdp_action(act);
+ /* fallthrough */
+ case XDP_ABORTED:
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
+ /* fallthrough -- handle aborts by dropping packet */
+ case XDP_DROP:
+ result = IXGBE_XDP_CONSUMED;
+ break;
+ }
+ rcu_read_unlock();
+ return result;
+}
+
+static struct ixgbe_rx_buffer *ixgbe_get_rx_buffer_zc(
+ struct ixgbe_ring *rx_ring,
+ unsigned int size)
+{
+ struct ixgbe_rx_buffer *bi;
+
+ bi = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
+
+ /* we are reusing so sync this buffer for CPU use */
+ dma_sync_single_range_for_cpu(rx_ring->dev,
+ bi->dma, 0,
+ size,
+ DMA_BIDIRECTIONAL);
+
+ return bi;
+}
+
+static void ixgbe_reuse_rx_buffer_zc(struct ixgbe_ring *rx_ring,
+ struct ixgbe_rx_buffer *obi)
+{
+ unsigned long mask = (unsigned long)rx_ring->xsk_umem->chunk_mask;
+ u64 hr = rx_ring->xsk_umem->headroom + XDP_PACKET_HEADROOM;
+ u16 nta = rx_ring->next_to_alloc;
+ struct ixgbe_rx_buffer *nbi;
+
+ nbi = &rx_ring->rx_buffer_info[rx_ring->next_to_alloc];
+ /* update, and store next to alloc */
+ nta++;
+ rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
+
+ /* transfer page from old buffer to new buffer */
+ nbi->dma = obi->dma & mask;
+ nbi->dma += hr;
+
+ nbi->addr = (void *)((unsigned long)obi->addr & mask);
+ nbi->addr += hr;
+
+ nbi->handle = obi->handle & mask;
+ nbi->handle += rx_ring->xsk_umem->headroom;
+
+ obi->addr = NULL;
+ obi->skb = NULL;
+}
+
+void ixgbe_zca_free(struct zero_copy_allocator *alloc, unsigned long handle)
+{
+ struct ixgbe_rx_buffer *bi;
+ struct ixgbe_ring *rx_ring;
+ u64 hr, mask;
+ u16 nta;
+
+ rx_ring = container_of(alloc, struct ixgbe_ring, zca);
+ hr = rx_ring->xsk_umem->headroom + XDP_PACKET_HEADROOM;
+ mask = rx_ring->xsk_umem->chunk_mask;
+
+ nta = rx_ring->next_to_alloc;
+ bi = rx_ring->rx_buffer_info;
+
+ nta++;
+ rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
+
+ handle &= mask;
+
+ bi->dma = xdp_umem_get_dma(rx_ring->xsk_umem, handle);
+ bi->dma += hr;
+
+ bi->addr = xdp_umem_get_data(rx_ring->xsk_umem, handle);
+ bi->addr += hr;
+
+ bi->handle = (u64)handle + rx_ring->xsk_umem->headroom;
+}
+
+static bool ixgbe_alloc_buffer_zc(struct ixgbe_ring *rx_ring,
+ struct ixgbe_rx_buffer *bi)
+{
+ struct xdp_umem *umem = rx_ring->xsk_umem;
+ void *addr = bi->addr;
+ u64 handle, hr;
+
+ if (addr)
+ return true;
+
+ if (!xsk_umem_peek_addr(umem, &handle)) {
+ rx_ring->rx_stats.alloc_rx_page_failed++;
+ return false;
+ }
+
+ hr = umem->headroom + XDP_PACKET_HEADROOM;
+
+ bi->dma = xdp_umem_get_dma(umem, handle);
+ bi->dma += hr;
+
+ bi->addr = xdp_umem_get_data(umem, handle);
+ bi->addr += hr;
+
+ bi->handle = handle + umem->headroom;
+
+ xsk_umem_discard_addr(umem);
+ return true;
+}
+
+static bool ixgbe_alloc_buffer_slow_zc(struct ixgbe_ring *rx_ring,
+ struct ixgbe_rx_buffer *bi)
+{
+ struct xdp_umem *umem = rx_ring->xsk_umem;
+ u64 handle, hr;
+
+ if (!xsk_umem_peek_addr_rq(umem, &handle)) {
+ rx_ring->rx_stats.alloc_rx_page_failed++;
+ return false;
+ }
+
+ handle &= rx_ring->xsk_umem->chunk_mask;
+
+ hr = umem->headroom + XDP_PACKET_HEADROOM;
+
+ bi->dma = xdp_umem_get_dma(umem, handle);
+ bi->dma += hr;
+
+ bi->addr = xdp_umem_get_data(umem, handle);
+ bi->addr += hr;
+
+ bi->handle = handle + umem->headroom;
+
+ xsk_umem_discard_addr_rq(umem);
+ return true;
+}
+
+static __always_inline bool __ixgbe_alloc_rx_buffers_zc(
+ struct ixgbe_ring *rx_ring,
+ u16 cleaned_count,
+ bool alloc(struct ixgbe_ring *rx_ring,
+ struct ixgbe_rx_buffer *bi))
+{
+ union ixgbe_adv_rx_desc *rx_desc;
+ struct ixgbe_rx_buffer *bi;
+ u16 i = rx_ring->next_to_use;
+ bool ok = true;
+
+ /* nothing to do */
+ if (!cleaned_count)
+ return true;
+
+ rx_desc = IXGBE_RX_DESC(rx_ring, i);
+ bi = &rx_ring->rx_buffer_info[i];
+ i -= rx_ring->count;
+
+ do {
+ if (!alloc(rx_ring, bi)) {
+ ok = false;
+ break;
+ }
+
+ /* sync the buffer for use by the device */
+ dma_sync_single_range_for_device(rx_ring->dev, bi->dma,
+ bi->page_offset,
+ rx_ring->rx_buf_len,
+ DMA_BIDIRECTIONAL);
+
+ /* Refresh the desc even if buffer_addrs didn't change
+ * because each write-back erases this info.
+ */
+ rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
+
+ rx_desc++;
+ bi++;
+ i++;
+ if (unlikely(!i)) {
+ rx_desc = IXGBE_RX_DESC(rx_ring, 0);
+ bi = rx_ring->rx_buffer_info;
+ i -= rx_ring->count;
+ }
+
+ /* clear the length for the next_to_use descriptor */
+ rx_desc->wb.upper.length = 0;
+
+ cleaned_count--;
+ } while (cleaned_count);
+
+ i += rx_ring->count;
+
+ if (rx_ring->next_to_use != i) {
+ rx_ring->next_to_use = i;
+
+ /* update next to alloc since we have filled the ring */
+ rx_ring->next_to_alloc = i;
+
+ /* Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch. (Only
+ * applicable for weak-ordered memory model archs,
+ * such as IA-64).
+ */
+ wmb();
+ writel(i, rx_ring->tail);
+ }
+
+ return ok;
+}
+
+void ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 count)
+{
+ __ixgbe_alloc_rx_buffers_zc(rx_ring, count,
+ ixgbe_alloc_buffer_slow_zc);
+}
+
+static bool ixgbe_alloc_rx_buffers_fast_zc(struct ixgbe_ring *rx_ring,
+ u16 count)
+{
+ return __ixgbe_alloc_rx_buffers_zc(rx_ring, count,
+ ixgbe_alloc_buffer_zc);
+}
+
+static struct sk_buff *ixgbe_construct_skb_zc(struct ixgbe_ring *rx_ring,
+ struct ixgbe_rx_buffer *bi,
+ struct xdp_buff *xdp)
+{
+ unsigned int metasize = xdp->data - xdp->data_meta;
+ unsigned int datasize = xdp->data_end - xdp->data;
+ struct sk_buff *skb;
+
+ /* allocate a skb to store the frags */
+ skb = __napi_alloc_skb(&rx_ring->q_vector->napi,
+ xdp->data_end - xdp->data_hard_start,
+ GFP_ATOMIC | __GFP_NOWARN);
+ if (unlikely(!skb))
+ return NULL;
+
+ skb_reserve(skb, xdp->data - xdp->data_hard_start);
+ memcpy(__skb_put(skb, datasize), xdp->data, datasize);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+
+ ixgbe_reuse_rx_buffer_zc(rx_ring, bi);
+ return skb;
+}
+
+static void ixgbe_inc_ntc(struct ixgbe_ring *rx_ring)
+{
+ u32 ntc = rx_ring->next_to_clean + 1;
+
+ ntc = (ntc < rx_ring->count) ? ntc : 0;
+ rx_ring->next_to_clean = ntc;
+ prefetch(IXGBE_RX_DESC(rx_ring, ntc));
+}
+
+int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector,
+ struct ixgbe_ring *rx_ring,
+ const int budget)
+{
+ unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ u16 cleaned_count = ixgbe_desc_unused(rx_ring);
+ unsigned int xdp_res, xdp_xmit = 0;
+ bool failure = false;
+ struct sk_buff *skb;
+ struct xdp_buff xdp;
+
+ xdp.rxq = &rx_ring->xdp_rxq;
+
+ while (likely(total_rx_packets < budget)) {
+ union ixgbe_adv_rx_desc *rx_desc;
+ struct ixgbe_rx_buffer *bi;
+ unsigned int size;
+
+ /* return some buffers to hardware, one at a time is too slow */
+ if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) {
+ failure = failure ||
+ !ixgbe_alloc_rx_buffers_fast_zc(
+ rx_ring,
+ cleaned_count);
+ cleaned_count = 0;
+ }
+
+ rx_desc = IXGBE_RX_DESC(rx_ring, rx_ring->next_to_clean);
+ size = le16_to_cpu(rx_desc->wb.upper.length);
+ if (!size)
+ break;
+
+ /* This memory barrier is needed to keep us from reading
+ * any other fields out of the rx_desc until we know the
+ * descriptor has been written back
+ */
+ dma_rmb();
+
+ bi = ixgbe_get_rx_buffer_zc(rx_ring, size);
+
+ if (unlikely(!ixgbe_test_staterr(rx_desc,
+ IXGBE_RXD_STAT_EOP))) {
+ struct ixgbe_rx_buffer *next_bi;
+
+ ixgbe_reuse_rx_buffer_zc(rx_ring, bi);
+ ixgbe_inc_ntc(rx_ring);
+ next_bi = &rx_ring->rx_buffer_info[
+ rx_ring->next_to_clean];
+ next_bi->skb = ERR_PTR(-EINVAL);
+ continue;
+ }
+
+ if (unlikely(bi->skb)) {
+ ixgbe_reuse_rx_buffer_zc(rx_ring, bi);
+ ixgbe_inc_ntc(rx_ring);
+ continue;
+ }
+
+ xdp.data = bi->addr;
+ xdp.data_meta = xdp.data;
+ xdp.data_hard_start = xdp.data - XDP_PACKET_HEADROOM;
+ xdp.data_end = xdp.data + size;
+ xdp.handle = bi->handle;
+
+ xdp_res = ixgbe_run_xdp_zc(adapter, rx_ring, &xdp);
+
+ if (xdp_res) {
+ if (xdp_res & (IXGBE_XDP_TX | IXGBE_XDP_REDIR)) {
+ xdp_xmit |= xdp_res;
+ bi->addr = NULL;
+ bi->skb = NULL;
+ } else {
+ ixgbe_reuse_rx_buffer_zc(rx_ring, bi);
+ }
+ total_rx_packets++;
+ total_rx_bytes += size;
+
+ cleaned_count++;
+ ixgbe_inc_ntc(rx_ring);
+ continue;
+ }
+
+ /* XDP_PASS path */
+ skb = ixgbe_construct_skb_zc(rx_ring, bi, &xdp);
+ if (!skb) {
+ rx_ring->rx_stats.alloc_rx_buff_failed++;
+ break;
+ }
+
+ cleaned_count++;
+ ixgbe_inc_ntc(rx_ring);
+
+ if (eth_skb_pad(skb))
+ continue;
+
+ total_rx_bytes += skb->len;
+ total_rx_packets++;
+
+ ixgbe_process_skb_fields(rx_ring, rx_desc, skb);
+ ixgbe_rx_skb(q_vector, skb);
+ }
+
+ if (xdp_xmit & IXGBE_XDP_REDIR)
+ xdp_do_flush_map();
+
+ if (xdp_xmit & IXGBE_XDP_TX) {
+ struct ixgbe_ring *ring = adapter->xdp_ring[smp_processor_id()];
+
+ /* Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch.
+ */
+ wmb();
+ writel(ring->next_to_use, ring->tail);
+ }
+
+ u64_stats_update_begin(&rx_ring->syncp);
+ rx_ring->stats.packets += total_rx_packets;
+ rx_ring->stats.bytes += total_rx_bytes;
+ u64_stats_update_end(&rx_ring->syncp);
+ q_vector->rx.total_packets += total_rx_packets;
+ q_vector->rx.total_bytes += total_rx_bytes;
+
+ return failure ? budget : (int)total_rx_packets;
+}
+
+void ixgbe_xsk_clean_rx_ring(struct ixgbe_ring *rx_ring)
+{
+ u16 i = rx_ring->next_to_clean;
+ struct ixgbe_rx_buffer *bi = &rx_ring->rx_buffer_info[i];
+
+ while (i != rx_ring->next_to_alloc) {
+ xsk_umem_fq_reuse(rx_ring->xsk_umem, bi->handle);
+ i++;
+ bi++;
+ if (i == rx_ring->count) {
+ i = 0;
+ bi = rx_ring->rx_buffer_info;
+ }
+ }
+}
--
2.17.1
^ permalink raw reply related
* [PATCH 2/5] ixgbe: move common Rx functions to ixgbe_txrx_common.h
From: Björn Töpel @ 2018-09-24 16:35 UTC (permalink / raw)
To: jeffrey.t.kirsher, intel-wired-lan
Cc: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
daniel, netdev, brouer, u9012063, tuc
In-Reply-To: <20180924163557.1187-1-bjorn.topel@gmail.com>
From: Björn Töpel <bjorn.topel@intel.com>
This patch prepares for the upcoming zero-copy Rx functionality, by
moving/changing linkage of common functions, used both by the regular
path and zero-copy path.
Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 29 +++++++------------
.../ethernet/intel/ixgbe/ixgbe_txrx_common.h | 26 +++++++++++++++++
2 files changed, 37 insertions(+), 18 deletions(-)
create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3b68e20c067d..3e2e6fb2215a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -40,6 +40,7 @@
#include "ixgbe_dcb_82599.h"
#include "ixgbe_sriov.h"
#include "ixgbe_model.h"
+#include "ixgbe_txrx_common.h"
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
@@ -1673,9 +1674,9 @@ static void ixgbe_update_rsc_stats(struct ixgbe_ring *rx_ring,
* order to populate the hash, checksum, VLAN, timestamp, protocol, and
* other fields within the skb.
**/
-static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
- union ixgbe_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
+void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb)
{
struct net_device *dev = rx_ring->netdev;
u32 flags = rx_ring->q_vector->adapter->flags;
@@ -1708,8 +1709,8 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
skb->protocol = eth_type_trans(skb, dev);
}
-static void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector,
- struct sk_buff *skb)
+void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector,
+ struct sk_buff *skb)
{
napi_gro_receive(&q_vector->napi, skb);
}
@@ -1868,9 +1869,9 @@ static void ixgbe_dma_sync_frag(struct ixgbe_ring *rx_ring,
*
* Returns true if an error was encountered and skb was freed.
**/
-static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring,
- union ixgbe_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
+bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring,
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb)
{
struct net_device *netdev = rx_ring->netdev;
@@ -2186,14 +2187,6 @@ static struct sk_buff *ixgbe_build_skb(struct ixgbe_ring *rx_ring,
return skb;
}
-#define IXGBE_XDP_PASS 0
-#define IXGBE_XDP_CONSUMED BIT(0)
-#define IXGBE_XDP_TX BIT(1)
-#define IXGBE_XDP_REDIR BIT(2)
-
-static int ixgbe_xmit_xdp_ring(struct ixgbe_adapter *adapter,
- struct xdp_frame *xdpf);
-
static struct sk_buff *ixgbe_run_xdp(struct ixgbe_adapter *adapter,
struct ixgbe_ring *rx_ring,
struct xdp_buff *xdp)
@@ -8465,8 +8458,8 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
}
#endif
-static int ixgbe_xmit_xdp_ring(struct ixgbe_adapter *adapter,
- struct xdp_frame *xdpf)
+int ixgbe_xmit_xdp_ring(struct ixgbe_adapter *adapter,
+ struct xdp_frame *xdpf)
{
struct ixgbe_ring *ring = adapter->xdp_ring[smp_processor_id()];
struct ixgbe_tx_buffer *tx_buffer;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
new file mode 100644
index 000000000000..3780d315b991
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2018 Intel Corporation. */
+
+#ifndef _IXGBE_TXRX_COMMON_H_
+#define _IXGBE_TXRX_COMMON_H_
+
+#define IXGBE_XDP_PASS 0
+#define IXGBE_XDP_CONSUMED BIT(0)
+#define IXGBE_XDP_TX BIT(1)
+#define IXGBE_XDP_REDIR BIT(2)
+
+int ixgbe_xmit_xdp_ring(struct ixgbe_adapter *adapter,
+ struct xdp_frame *xdpf);
+bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring,
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb);
+void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb);
+void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector,
+ struct sk_buff *skb);
+
+void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring);
+void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring);
+
+#endif /* #define _IXGBE_TXRX_COMMON_H_ */
--
2.17.1
^ permalink raw reply related
* [PATCH 1/5] ixgbe: added Rx/Tx ring disable/enable functions
From: Björn Töpel @ 2018-09-24 16:35 UTC (permalink / raw)
To: jeffrey.t.kirsher, intel-wired-lan
Cc: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
daniel, netdev, brouer, u9012063, tuc
In-Reply-To: <20180924163557.1187-1-bjorn.topel@gmail.com>
From: Björn Töpel <bjorn.topel@intel.com>
Add functions for Rx/Tx ring enable/disable. Instead of resetting the
whole device, only the affected ring is disabled or enabled.
This plumbing is used in later commits, when zero-copy AF_XDP support
is introduced.
Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 158 ++++++++++++++++++
2 files changed, 159 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5c6fd42e90ed..265db172042a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -271,6 +271,7 @@ enum ixgbe_ring_state_t {
__IXGBE_TX_DETECT_HANG,
__IXGBE_HANG_CHECK_ARMED,
__IXGBE_TX_XDP_RING,
+ __IXGBE_TX_DISABLED,
};
#define ring_uses_build_skb(ring) \
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index d4d47707662f..3b68e20c067d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8688,6 +8688,8 @@ static netdev_tx_t __ixgbe_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
tx_ring = ring ? ring : adapter->tx_ring[skb->queue_mapping];
+ if (unlikely(test_bit(__IXGBE_TX_DISABLED, &tx_ring->state)))
+ return NETDEV_TX_BUSY;
return ixgbe_xmit_frame_ring(skb, adapter, tx_ring);
}
@@ -10256,6 +10258,9 @@ static int ixgbe_xdp_xmit(struct net_device *dev, int n,
if (unlikely(!ring))
return -ENXIO;
+ if (unlikely(test_bit(__IXGBE_TX_DISABLED, &ring->state)))
+ return -ENXIO;
+
for (i = 0; i < n; i++) {
struct xdp_frame *xdpf = frames[i];
int err;
@@ -10322,6 +10327,159 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_xdp_xmit = ixgbe_xdp_xmit,
};
+static void ixgbe_disable_txr_hw(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring)
+{
+ unsigned long wait_delay, delay_interval;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u8 reg_idx = tx_ring->reg_idx;
+ int wait_loop;
+ u32 txdctl;
+
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
+
+ /* delay mechanism from ixgbe_disable_tx */
+ delay_interval = ixgbe_get_completion_timeout(adapter) / 100;
+
+ wait_loop = IXGBE_MAX_RX_DESC_POLL;
+ wait_delay = delay_interval;
+
+ while (wait_loop--) {
+ usleep_range(wait_delay, wait_delay + 10);
+ wait_delay += delay_interval * 2;
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
+
+ if (!(txdctl & IXGBE_TXDCTL_ENABLE))
+ return;
+ }
+
+ e_err(drv, "TXDCTL.ENABLE not cleared within the polling period\n");
+}
+
+static void ixgbe_disable_txr(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring)
+{
+ set_bit(__IXGBE_TX_DISABLED, &tx_ring->state);
+ ixgbe_disable_txr_hw(adapter, tx_ring);
+}
+
+static void ixgbe_disable_rxr_hw(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring)
+{
+ unsigned long wait_delay, delay_interval;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u8 reg_idx = rx_ring->reg_idx;
+ int wait_loop;
+ u32 rxdctl;
+
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
+ rxdctl &= ~IXGBE_RXDCTL_ENABLE;
+ rxdctl |= IXGBE_RXDCTL_SWFLSH;
+
+ /* write value back with RXDCTL.ENABLE bit cleared */
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
+
+ /* RXDCTL.EN may not change on 82598 if link is down, so skip it */
+ if (hw->mac.type == ixgbe_mac_82598EB &&
+ !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
+ return;
+
+ /* delay mechanism from ixgbe_disable_rx */
+ delay_interval = ixgbe_get_completion_timeout(adapter) / 100;
+
+ wait_loop = IXGBE_MAX_RX_DESC_POLL;
+ wait_delay = delay_interval;
+
+ while (wait_loop--) {
+ usleep_range(wait_delay, wait_delay + 10);
+ wait_delay += delay_interval * 2;
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
+
+ if (!(rxdctl & IXGBE_RXDCTL_ENABLE))
+ return;
+ }
+
+ e_err(drv, "RXDCTL.ENABLE not cleared within the polling period\n");
+}
+
+static void ixgbe_reset_txr_stats(struct ixgbe_ring *tx_ring)
+{
+ memset(&tx_ring->stats, 0, sizeof(tx_ring->stats));
+ memset(&tx_ring->tx_stats, 0, sizeof(tx_ring->tx_stats));
+}
+
+static void ixgbe_reset_rxr_stats(struct ixgbe_ring *rx_ring)
+{
+ memset(&rx_ring->stats, 0, sizeof(rx_ring->stats));
+ memset(&rx_ring->rx_stats, 0, sizeof(rx_ring->rx_stats));
+}
+
+/**
+ * ixgbe_txrx_ring_disable - Disable Rx/Tx/XDP Tx rings
+ * @adapter: adapter structure
+ * @ring: ring index
+ *
+ * This function disables a certain Rx/Tx/XDP Tx ring. The function
+ * assumes that the netdev is running.
+ **/
+void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring)
+{
+ struct ixgbe_ring *rx_ring, *tx_ring, *xdp_ring;
+
+ rx_ring = adapter->rx_ring[ring];
+ tx_ring = adapter->tx_ring[ring];
+ xdp_ring = adapter->xdp_ring[ring];
+
+ ixgbe_disable_txr(adapter, tx_ring);
+ if (xdp_ring)
+ ixgbe_disable_txr(adapter, xdp_ring);
+ ixgbe_disable_rxr_hw(adapter, rx_ring);
+
+ if (xdp_ring)
+ synchronize_sched();
+
+ /* Rx/Tx/XDP Tx share the same napi context. */
+ napi_disable(&rx_ring->q_vector->napi);
+
+ ixgbe_clean_tx_ring(tx_ring);
+ if (xdp_ring)
+ ixgbe_clean_tx_ring(xdp_ring);
+ ixgbe_clean_rx_ring(rx_ring);
+
+ ixgbe_reset_txr_stats(tx_ring);
+ if (xdp_ring)
+ ixgbe_reset_txr_stats(xdp_ring);
+ ixgbe_reset_rxr_stats(rx_ring);
+}
+
+/**
+ * ixgbe_txrx_ring_enable - Enable Rx/Tx/XDP Tx rings
+ * @adapter: adapter structure
+ * @ring: ring index
+ *
+ * This function enables a certain Rx/Tx/XDP Tx ring. The function
+ * assumes that the netdev is running.
+ **/
+void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring)
+{
+ struct ixgbe_ring *rx_ring, *tx_ring, *xdp_ring;
+
+ rx_ring = adapter->rx_ring[ring];
+ tx_ring = adapter->tx_ring[ring];
+ xdp_ring = adapter->xdp_ring[ring];
+
+ /* Rx/Tx/XDP Tx share the same napi context. */
+ napi_enable(&rx_ring->q_vector->napi);
+
+ ixgbe_configure_tx_ring(adapter, tx_ring);
+ if (xdp_ring)
+ ixgbe_configure_tx_ring(adapter, xdp_ring);
+ ixgbe_configure_rx_ring(adapter, rx_ring);
+
+ clear_bit(__IXGBE_TX_DISABLED, &tx_ring->state);
+ clear_bit(__IXGBE_TX_DISABLED, &xdp_ring->state);
+}
+
/**
* ixgbe_enumerate_functions - Get the number of ports this device has
* @adapter: adapter structure
--
2.17.1
^ permalink raw reply related
* [PATCH 0/5] Introducing ixgbe AF_XDP ZC support
From: Björn Töpel @ 2018-09-24 16:35 UTC (permalink / raw)
To: jeffrey.t.kirsher, intel-wired-lan
Cc: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
daniel, netdev, brouer, u9012063, tuc
From: Björn Töpel <bjorn.topel@intel.com>
This patch set introduces zero-copy AF_XDP support for Intel's ixgbe
driver.
The ixgbe zero-copy code is located in its own file ixgbe_xsk.[ch],
analogous to the i40e ZC support. Again, as in i40e, code paths have
been copied from the XDP path to the zero-copy path. Going forward we
will try to generalize more code between the AF_XDP ZC drivers, and
also reduce the heavy C&P.
We have run some benchmarks on a dual socket system with two Broadwell
E5 2660 @ 2.0 GHz with hyperthreading turned off. Each socket has 14
cores which gives a total of 28, but only two cores are used in these
experiments. One for TR/RX and one for the user space application. The
memory is DDR4 @ 2133 MT/s (1067 MHz) and the size of each DIMM is
8192MB and with 8 of those DIMMs in the system we have 64 GB of total
memory. The compiler used is GCC 7.3.0. The NIC is Intel
82599ES/X520-2 10Gbit/s using the ixgbe driver.
Below are the results in Mpps of the 82599ES/X520-2 NIC benchmark runs
for 64B and 1500B packets, generated by a commercial packet generator
HW blasting packets at full 10Gbit/s line rate. The results are with
retpoline and all other spectre and meltdown fixes.
AF_XDP performance 64B packets:
Benchmark XDP_DRV with zerocopy
rxdrop 14.7
txpush 14.6
l2fwd 11.1
AF_XDP performance 1500B packets:
Benchmark XDP_DRV with zerocopy
rxdrop 0.8
l2fwd 0.8
XDP performance on our system as a base line.
64B packets:
XDP stats CPU Mpps issue-pps
XDP-RX CPU 16 14.7 0
1500B packets:
XDP stats CPU Mpps issue-pps
XDP-RX CPU 16 0.8 0
The structure of the patch set is as follows:
Patch 1: Introduce Rx/Tx ring enable/disable functionality
Patch 2: Preparatory patche to ixgbe driver code for RX
Patch 3: ixgbe zero-copy support for RX
Patch 4: Preparatory patch to ixgbe driver code for TX
Patch 5: ixgbe zero-copy support for TX
Cheers!
Björn
Björn Töpel (5):
ixgbe: added Rx/Tx ring disable/enable functions
ixgbe: move common Rx functions to ixgbe_txrx_common.h
ixgbe: add AF_XDP zero-copy Rx support
ixgbe: move common Tx functions to ixgbe_txrx_common.h
ixgbe: add AF_XDP zero-copy Tx support
drivers/net/ethernet/intel/ixgbe/Makefile | 3 +-
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 27 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 290 ++++++-
.../ethernet/intel/ixgbe/ixgbe_txrx_common.h | 50 ++
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 814 ++++++++++++++++++
5 files changed, 1139 insertions(+), 45 deletions(-)
create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
--
2.17.1
^ 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