[RFC PATCH v4 19/19] dyndbg: RFC add linker rules to module.lds.h
Copy the DYNAMIC_DEBUG_DATA macro, that works in vmlinux.lds.h, into module.lds.h This does not work here The point of the KEEPS is to pack section pairs into consecutive memory, a property we need in order to drop the _ddebug.site pointer. The problem (ISTM) is that for linking vmlinux, the data is linked into .data (and the sections are subsumed), and it is is accessed by iterating beteween __(fstart|stop)___dyndbg(_sites)? symbols. That breaks down here cuz kernel/module.c specifically grabs the __dyndb* sections by name. I lack the linker-fu to sort this, so I left my commented out attempts, to show my errors. no-bisect: expect linker error Signed-off-by: Jim Cromie --- include/asm-generic/module.lds.h | 21 + 1 file changed, 21 insertions(+) diff --git a/include/asm-generic/module.lds.h b/include/asm-generic/module.lds.h index f210d5c1b78b..0074c5f2421b 100644 --- a/include/asm-generic/module.lds.h +++ b/include/asm-generic/module.lds.h @@ -7,4 +7,25 @@ * Empty for the asm-generic header. */ +/* implement dynamic printk debug section packing */ +#if defined(CONFIG_DYNAMIC_DEBUG) || \ + (defined(CONFIG_DYNAMIC_DEBUG_CORE) \ +&& defined(DYNAMIC_DEBUG_MODULE)) +#define DYNAMIC_DEBUG_DATA() \ + . = ALIGN(8); \ + KEEP(*(__dyndbg_sites .gnu.linkonce.dyndbg_site)) \ + KEEP(*(__dyndbg .gnu.linkonce.dyndbg)) +#else +#define DYNAMIC_DEBUG_DATA() +#endif + +SECTIONS { +__dyndbg : { (*(__dyndbg .gnu.linkonce.dyndbg)) } +__dyndbg_sites : { (*(__dyndbg_sites .gnu.linkonce.dyndbg_site)) } + + //.data.dyndbg : { DYNAMIC_DEBUG_DATA() } // syntax ok + //: { DYNAMIC_DEBUG_DATA() } + //DYNAMIC_DEBUG_DATA() +} + #endif /* __ASM_GENERIC_MODULE_LDS_H */ -- 2.29.2
[RFC PATCH v4 16/19] dyndbg: prevent build bugs via -DNO_DYNAMIC_DEBUG_TABLE
The next patch adds DEFINE_DYNAMIC_DEBUG_TABLE(), which breaks some subtrees with special compile constraints (efi etc). Avoid this by adding a define to suppress the *remote declaration* done by DEFINE_DYNAMIC_DEBUG_TABLE(), automatically, on behalf of all possible users of pr_debug. Signed-off-by: Jim Cromie --- arch/x86/boot/compressed/Makefile | 1 + arch/x86/entry/vdso/Makefile | 3 +++ arch/x86/purgatory/Makefile | 1 + drivers/firmware/efi/libstub/Makefile | 3 ++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index e0bc3988c3fa..ada4eb960d95 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -31,6 +31,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ KBUILD_CFLAGS := -m$(BITS) -O2 KBUILD_CFLAGS += -fno-strict-aliasing -fPIE KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +KBUILD_CFLAGS += -DNO_DYNAMIC_DEBUG_TABLE cflags-$(CONFIG_X86_32) := -march=i386 cflags-$(CONFIG_X86_64) := -mcmodel=small -mno-red-zone KBUILD_CFLAGS += $(cflags-y) diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 05c4abc2fdfd..619878f2c427 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -29,6 +29,9 @@ vobjs32-y := vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o vobjs32-y += vdso32/vclock_gettime.o vobjs-$(CONFIG_X86_SGX)+= vsgx.o +# avoid a x86_64_RELATIVE error +KBUILD_CFLAGS += -DNO_DYNAMIC_DEBUG_TABLE + # files to link into kernel obj-y += vma.o extable.o KASAN_SANITIZE_vma.o := y diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 95ea17a9d20c..95ba7b18410f 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile @@ -35,6 +35,7 @@ PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss -g0 PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING PURGATORY_CFLAGS += -fno-stack-protector +PURGATORY_CFLAGS += -DNO_DYNAMIC_DEBUG_TABLE # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That # in turn leaves some undefined symbols like __fentry__ in purgatory and not diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index c23466e05e60..def8febefbd3 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -13,7 +13,8 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ -Wno-pointer-sign \ $(call cc-disable-warning, address-of-packed-member) \ $(call cc-disable-warning, gnu) \ - -fno-asynchronous-unwind-tables + -fno-asynchronous-unwind-tables \ + -DNO_DYNAMIC_DEBUG_TABLE # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly # disable the stackleak plugin -- 2.29.2
[RFC PATCH v4 18/19] dyndbg: shuffle ddebug_table fields
In preparation to unionize structs _ddebug & ddebug_table, shuffle fields in latter so they match the layout of the former. This MAY simplify initialization of the header field, in particular by preserving *sites. It also sets up a later conversion to a flex-array ddebugs[]. This step is mostly to isolate/prove no breakage before HEAD++ Signed-off-by: Jim Cromie --- include/linux/dynamic_debug.h | 29 + lib/dynamic_debug.c | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 229cfd81ffb3..22f11218047f 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -66,6 +66,35 @@ struct _ddebug { #endif } __aligned(8); +/* this pair of header structs correspond quite deeply to struct + * _ddebug(|_site)s above; they are also created into __dyndbg* + * sections (by DEFINE_DYNAMIC_DEBUG_TABLE), and should be unionized + * with them to reinforce this. + * + * struct _ddebug_header is the important one, it has enough space to + * take struct ddebug_table's job, ie: link together into a list, and + * keep track of the modname & _ddebug(|_sites) vectors. + * + * Its other job is handled by its placement in the front of a + * module's _ddebug[N] entries. Each _ddebug knows its N, so the + * header's address is computable, and its site pointer is available + * to get _ddebug_sites[N]. Then we can drop _ddebug.sites, regaining + * parity with original _ddebug footprint. + * + * Eventually, N will index a fetch from a compressed block, or for + * enabled callsites, a hash. A global hash is probably adequate, if + * ~5k elements doesnt degrade access time. + */ +struct _ddebug_site_header { + /* we have 24 bytes total here, all currently unused */ +} __aligned(8); + +struct _ddebug_header { + struct _ddebug_site* sites; + struct list_head link; + const char* mod_name; + unsigned num_ddebugs; +} __aligned(8); #if defined(CONFIG_DYNAMIC_DEBUG_CORE) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index c1a7345277eb..5d1ce7f21c30 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -45,11 +45,11 @@ extern struct _ddebug_site __start___dyndbg_sites[]; extern struct _ddebug_site __stop___dyndbg_sites[]; struct ddebug_table { + struct _ddebug_site *sites; struct list_head link; const char *mod_name; unsigned int num_ddebugs; struct _ddebug *ddebugs; - struct _ddebug_site *sites; }; struct ddebug_query { -- 2.29.2
[RFC PATCH v4 05/19] dyndbg: hoist ->site out of ddebug_match_site
A coming change adds _get/_put abstraction on the site pointer, to allow managing site info more flexibly. The get/put pattern is best done at a single lexical scope, where its more obviously correct, so hoist the ->site ref out of ddebug_match_site, and pass it in instead. no functional changes Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index da732e0c56e3..abe3382aabd5 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -143,10 +143,9 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg) } static int ddebug_match_site(const struct ddebug_query *query, -const struct _ddebug *dp) +const struct _ddebug *dp, +const struct _ddebug_site *dc) { - struct _ddebug_site *dc; - /* match against the format */ if (query->format) { if (*query->format == '^') { @@ -167,7 +166,6 @@ static int ddebug_match_site(const struct ddebug_query *query, dp->lineno > query->last_lineno) return false; - dc = dp->site; if (!dc) { /* site info has been dropped, so query cannot test these fields */ if (query->filename || query->function) @@ -219,9 +217,9 @@ static int ddebug_change(const struct ddebug_query *query, for (i = 0; i < dt->num_ddebugs; i++) { struct _ddebug *dp = &dt->ddebugs[i]; - struct _ddebug_site *dc; + struct _ddebug_site *dc = dp->site; - if (!ddebug_match_site(query, dp)) + if (!ddebug_match_site(query, dp, dc)) continue; nfound++; -- 2.29.2
[RFC PATCH v4 06/19] dyndbg: accept null site in ddebug_change
fix a debug-print that includes site info, by adding an alternate debug message that does not. no functional changes. Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index abe3382aabd5..151e55ab6bb5 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -235,10 +235,17 @@ static int ddebug_change(const struct ddebug_query *query, static_branch_enable(&dp->key.dd_key_true); #endif dp->flags = newflags; - v2pr_info("changed %s:%d [%s]%s =%s\n", -trim_prefix(dc->filename), dp->lineno, -dt->mod_name, dc->function, -ddebug_describe_flags(dp->flags, &fbuf)); + + if (dc) + v2pr_info("changed %s:%d [%s]%s =%s\n", + trim_prefix(dc->filename), dp->lineno, + dt->mod_name, dc->function, + ddebug_describe_flags(dp->flags, &fbuf)); + else + v2pr_info("changed %s:%d =%s \"%s\"\n", + dt->mod_name, dp->lineno, + ddebug_describe_flags(dp->flags, &fbuf), + dp->format); } } mutex_unlock(&ddebug_lock); -- 2.29.2
[RFC PATCH v4 08/19] dyndbg: accept null site in ddebug_proc_show
Accept a ddebug record with a null site pointer, and write abbreviated output for that record that doesn't include site info (but does include line-number, since that can be used in >control queries). Also add a 2nd header line with a template for the new output. Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 0c535f3c2ba9..1f0cac4a66af 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -918,18 +918,27 @@ static int ddebug_proc_show(struct seq_file *m, void *p) if (p == SEQ_START_TOKEN) { seq_puts(m, -"# filename:lineno [module]function flags format\n"); +"#: filename:lineno [module]function flags format\n" +"#| [module]:lineno flags format\n" + ); return 0; } dc = dp->site; - - seq_printf(m, "%s:%u [%s]%s =%s \"", - trim_prefix(dc->filename), dp->lineno, - iter->table->mod_name, dc->function, - ddebug_describe_flags(dp->flags, &flags)); - seq_escape(m, dp->format, "\t\r\n\""); - seq_puts(m, "\"\n"); + if (dc) { + seq_printf(m, "%s:%u [%s]%s =%s \"", + trim_prefix(dc->filename), dp->lineno, + iter->table->mod_name, dc->function, + ddebug_describe_flags(dp->flags, &flags)); + seq_escape(m, dp->format, "\t\r\n\""); + seq_puts(m, "\"\n"); + } else { + seq_printf(m, "[%s]:%u =%s \"", + iter->table->mod_name, dp->lineno, + ddebug_describe_flags(dp->flags, &flags)); + seq_escape(m, dp->format, "\t\r\n\""); + seq_puts(m, "\"\n"); + } return 0; } -- 2.29.2
[RFC PATCH v4 15/19] dyndbg: add _index to struct _ddebug
We currently use dp->site to map: &__dyndbg[N] -> &__dyndbg_sites[N]. We want to drop site, new _ddebug._index provides the N. The mapping is done in ddebug_site_get(): For builtin modules, a _ddebug *ptr is between __start___dyndbg and __stop___dyndbg, and we can use &__start___dyndbg_sites[N] directly. For loadable modules, we still need work, so we print rubbish, and just return site pointer (which is correct). ddebug_add_module() handles _index initialization: Its new task is to number each module consecutively, so it gets new base arg to pass the next starting index. To actually drop site, We need both the module's __dyndbg* section addys, and we need their relative placement to have a base-to-base offset. PLAN - a table header connecting 2 tables. - ddebug_table points to both __dyndbgs & __dyndbg_sites. but *ddebugs & *sites are independent. no path from ddebugs[n] -> ddebug_sites[n] If we have a header record in-situ, which keeps the site pointer we seek to eliminate from _ddebug, and its in element[0] of both vectors, we can go: ddebugs[n] -> ddebugs[0] -> containerof -> site[n] union ddebug_table_header { struct ddebug_table *owner; struct _ddebug item; } and struct ddebug_table_vector { struct ddebug_table *owner; struct _ddebug vector[]; } Signed-off-by: Jim Cromie --- include/linux/dynamic_debug.h | 2 ++ lib/dynamic_debug.c | 40 +-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 7d33475d226a..18689db0e2c0 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -29,6 +29,7 @@ struct _ddebug { /* format is always needed, lineno shares word with flags */ const char *format; const unsigned lineno:18; + unsigned _index:14; /* * The flags field controls the behaviour at the callsite. * The bits here are changed dynamically when the user @@ -56,6 +57,7 @@ struct _ddebug { #define _DPRINTK_FLAGS_DEFAULT 0 #endif unsigned int flags:8; + #ifdef CONFIG_JUMP_LABEL union { struct static_key_true dd_key_true; diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 1f59407b6a83..54737647556c 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -123,6 +123,8 @@ do { \ #define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__) #define v2pr_info(fmt, ...)vnpr_info(2, fmt, ##__VA_ARGS__) #define v3pr_info(fmt, ...)vnpr_info(3, fmt, ##__VA_ARGS__) +#define v4pr_info(fmt, ...)vnpr_info(4, fmt, ##__VA_ARGS__) +#define v5pr_info(fmt, ...)vnpr_info(5, fmt, ##__VA_ARGS__) static void vpr_info_dq(const struct ddebug_query *query, const char *msg) { @@ -146,7 +148,17 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg) static struct _ddebug_site *ddebug_site_get(struct _ddebug *dp) { - return dp->site; /* passthru abstraction */ + v4pr_info("get %d: %s.%s.%d\n", dp->_index, dp->site->modname, + dp->site->function, dp->lineno); + + if (dp >= __start___dyndbg && dp < __stop___dyndbg) { + v4pr_info(" is builtin: %d %ld\n", dp->_index, dp - __start___dyndbg); + return &__start___dyndbg_sites[ dp - __start___dyndbg ]; + } else { + v3pr_info(" is loaded: %d %ld\n", dp->_index, dp - __start___dyndbg); + return dp->site; + } + return dp->site; } static inline void ddebug_site_put(struct _ddebug *dp) { @@ -1034,10 +1046,12 @@ static const struct proc_ops proc_fops = { * Allocate a new ddebug_table for the given module * and add it to the global list. */ -int ddebug_add_module(struct _ddebug *tab, struct _ddebug_site *sites, - unsigned int numdbgs, const char *modname) +static int __ddebug_add_module(struct _ddebug *tab, struct _ddebug_site *sites, + unsigned numdbgs, unsigned base, + const char *modname) { struct ddebug_table *dt; + int i; dt = kzalloc(sizeof(*dt), GFP_KERNEL); if (dt == NULL) { @@ -1055,6 +1069,13 @@ int ddebug_add_module(struct _ddebug *tab, struct _ddebug_site *sites, dt->ddebugs = tab; dt->sites = sites; + v3pr_info("add-module: %s\n", modname); + for (i = 0; i < numdbgs; i++) { + tab[i]._index = base++; + v3pr_info(" %d %d %s.%s.%d\n", i, tab[i]._index, modname, + tab[i].site->function, tab[i].lineno); + } + mutex_lock(&ddebug_lock); list_add(&dt->link, &ddebug_tables); mutex_unlock(&ddebug_lock); @@ -1063,6 +1084,12 @@ int ddebug_add_module(struct _ddebug *tab, struct _ddebug_site *sites, return 0; } +int ddebug_add_modul
[RFC PATCH v4 17/19] dyndbg: RFC - DECLARE/DEFINE_DYNAMIC_DEBUG_TABLE
V4-proto - now currently diet-3i Simplify: .gnu.linkonce._mod_.dyndbg -> .gnu.linkonce.dyndbg ie drop _mod_ This puts a single header record at front of the vectors, solving 2 problems (discussed below) simultaneously: - header in front, allowing flex-array rep of layout. - single header, not per-module. adequate for needs, no wasted space. this now appears to work - get: dp range-check good on builtin, !builtin. todo: - _sym_##_site symbols in init/main.i still busted - _index init in __ddebug_add_module - cleanup commentary below. DEFINE_DYNAMIC_DEBUG_TABLE is based on DECLARE_DYNAMIC_DEBUG_METADATA. Like its model, it creates/allocates a pair of structs: _ddebug & _ddebug_site, and inits them distinctively. Its purpose is to create an in-situ module-header-pair for each module's sub-vectors of _ddebug[], _ddebug_sites[]. Once the header-pair is reliably linked into the vectors, code can get from _ddebug[N] to the header-pair, then to _ddebug_sites[N] at runtime by saving N into _ddebug._index during init. With this, we can drop the site pointer in struct _ddebug. Eventually, this module-header-pair can be adapted to be an in-situ replacement for the separately allocated struct ddebug_tables, and be linked into the ddebug_tables list. RFC, NOTES: DYNAMIC_DEBUG is a 'transparent' facility, in that uses of pr_debug get extra features without additional api. Because of this, DEFINE_DYNAMIC_DEBUG_TABLE is 'transparently' invoked by dynamic_debug.h on behalf of all its (indirect) users, including printk.h. IOW this has wide effects; it results in multiple redundant declarations of header records, even single object files may get multiple copies. Using .gnu.linkonce._mod_.dyndbg(|_site) section names and "__used __weak " seems to resolve the redundancies. I havent tried with clang. In vmlinux-lds.h, the 2 KEEPs are modified to append those 2 new header sections to their respective existing __dyndbg* sections, in an interleaved manner. This places the header records immediately after the modules' block of _ddebug*s, in a knowable offset from &__dyndbg[0]. scripts/Makefile.lib gets a new -DKBUILD_MODSYM defn, with a value like KBUILD_MODNAME, except that its not __stringified. It is used to create a pair of module-ish named variables: _sym_##_dyndbg_base. For some non-obvious reason, the substitution doesnt work, resulting in per-module symbol names like KBUILD_MODSYM_dyndbg_base. This subtly alters the header initialization and is_dyndbg_header_pair(), which is used in __init to find the headers adjacent to each modules' block of _ddebug records. This isnt fatal to the plan; we just need the storage reserved where its accessible by known offset from the _ddebug[N] record of an enabled pr-debug. But it would be nice to have the symbol names consistent with the intent. I looked for a MODULE_SINGLETON(name_suffix) to use, similarly to how UNIQUE_ID is used to construct names, but found nothing. The .gnu.linkonce._mod_. works to eliminate all the extra headers in each module, but a problem remains; it adds unneeded headers for modules with zero pr-debugs. So Im seeing ~1500 extra headers. I tried several flavors of conditional linking, now think I want/need a linker-script language extension: KEEP ( *(__dyndbg) AND *(.gnu.linkonce.dyndbg) ) # my need KEEP ( *(foo_tbl) OR *(.gnu.linkonce.foo_alt) ) # for completeness I've managed to alter ld's grammar, but its only compile tested, and is missing the conditional linking pieces. Since this patchset's value proposition is a memory shrink, ~1500 extra headers is fatal, and this patchset must be a slow-cook. V4 todo: Time to simplify, drop _mod_, and change _ddebug.module_index to ._index, indicating that its no longer keyed to module, but to the whole compilation unit, which for the kernel includes all the builtin modules. loadable modules should get their own. tbt. this could obsolete all the above problems. Signed-off-by: Jim Cromie --- drivers/gpu/drm/i915/i915_drv.c | 2 + include/asm-generic/vmlinux.lds.h | 27 +--- include/linux/dynamic_debug.h | 100 +- lib/dynamic_debug.c | 27 +--- scripts/Makefile.lib | 2 + 5 files changed, 139 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8e9cb44e66e5..51163e0d40cf 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -91,6 +91,8 @@ static const struct drm_driver driver; +//DEFINE_DYNAMIC_DEBUG_TABLE(); + static int i915_get_bridge_dev(struct drm_i915_private *dev_priv) { int domain = pci_domain_nr(dev_priv->drm.pdev->bus); diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 4f2af9de2f03..482d94078785 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -335,6 +335,22 @@ KEEP(*(.dtb.init.rodata))
[RFC PATCH v4 14/19] dyndbg: add ddebug_site(_get|_put) abstraction
Replace direct ->site refs with _get(),_put() internal API. Right now, _get() just returns ->site and _put() does nothing. Later we can replace that implementation with one using ->module_index to fetch then forget site data dynamically. Several approaches are possible: A: !site -> fill from backing store 1st try at this is/was using zram. At init, it copied each callsite into a zs-allocation, and all site-> refs afterward went thru _get/_put to zs-map on demand, and zs-unmap the site info. This worked until I tried to keep callsites mapped while they're enabled, when it gave lockdep warns/panics. IIRC theres a zram patchset doing something with locking; I need to retry this approach, even if other options are better, this might be a validating use case. B: block store Another approach is to compress the new linker section, using some algorithm thats good at indexed decompression. I probed this approach, using objcopy, unsuccessfully: objcopy --dump-section __dyndbg=dd \ --dump-section __dyndbg_sites=ddsites $IMG >From vmlinux.o dumps were mostly empty (pre-link/reloc data?) and vmlinux didnt have the section. C: callsite composed from __dyndbg[N] & __dyndbg_site[N] We know _ddebug records are in a vector, either in the builtin __dyndbg linker section, or the same from a modprobed one. The builtin section has all builtin module sub-sections catenated dogether. At init, we iterate over the section, and "parse it" by creating a ddebug_table for each module with prdebugs. ddebug_table.num_debugs remembers the size of each modules' vector of prdebugs. We need a few things: - _ddebug.index field, which knows offset to start of this sub-vector. this new field will be "free" because the struct has padding. it can be initialized during init, then RO. - a back-pointer at the beginning of the sub-vector, to the ddebug_table "owning" (but not containing) this sub-vector of prdebugs. If we had both, we could get from the ddebug element to its vector root, back up to the owning ddebug_table, then down to the _callsite vector, and index to the right element. While slower than a pointer deref, this is a cold path, and it allows elimination of the per-callsite pointer member, thus greater density of the sections, and still can support sparse site info. That back-pointer feels tricky. It needs to be 1st in the sub-vector D: (C1?) add a header record to each sub-vector If we can insert a header record into each modules' __dyndbg* section sub-vectors, we can simplify the cold path above; a single sites* pointer in the header can give us access to __dyndbg_sites[N] Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 31 +-- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index be2e97ae2da9..1f59407b6a83 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -144,6 +144,14 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg) query->first_lineno, query->last_lineno); } +static struct _ddebug_site *ddebug_site_get(struct _ddebug *dp) +{ + return dp->site; /* passthru abstraction */ +} +static inline void ddebug_site_put(struct _ddebug *dp) +{ +} + static int ddebug_match_site(const struct ddebug_query *query, const struct _ddebug *dp, const struct _ddebug_site *dc) @@ -239,16 +247,18 @@ static int ddebug_change(const struct ddebug_query *query, for (i = 0; i < dt->num_ddebugs; i++) { struct _ddebug *dp = &dt->ddebugs[i]; - struct _ddebug_site *dc = dp->site; + struct _ddebug_site *dc; + + dc = ddebug_site_get(dp); if (!ddebug_match_site(query, dp, dc)) - continue; + goto skipsite; nfound++; newflags = (dp->flags & modifiers->mask) | modifiers->flags; if (newflags == dp->flags) - continue; + goto skipsite; ddebug_alter_site(dp, modifiers); @@ -264,6 +274,9 @@ static int ddebug_change(const struct ddebug_query *query, dt->mod_name, dp->lineno, ddebug_describe_flags(dp->flags, &fbuf), dp->format); + + skipsite: + ddebug_site_put(dp); } } mutex_unlock(&ddebug_lock); @@ -633,11 +646,11 @@ static int remaining(int wrote) return 0; } -static char *__dynamic_emit_prefix(const struct _ddebug *dp, char *buf) +static char *__dynamic_emit_prefix(struct _ddebug *dp, char *buf) { int pos_after_tid; int pos = 0; - co
[RFC PATCH v4 13/19] dyndbg+module: expose ddebug_sites to modules
In order to drop the pointer connecting _ddebug's to _ddebug_sites, we need to elevate the latter; we need to track it in (internal) ddebug_tables, and set it in ddebug_add_module. That last part exposes it by interface to module.c, so we add a field to load_info, and adjust load_module to initialize it from the elf section. Its possible that this closes a "hole" created when __dyndbg_sites section was added, in that the section wasn't "managed" directly, and could conceivably get lost later. I never saw any misbehavior loading i915.ko into a vm, but still.. TBD/RFC: these 2 vectors should be in a single struct. if this struct can have ddebugs[], ie a flex-array, then container_of can get us to the sites*, yielding &ddebug_sites[N], and allowing to drop _ddebug.site The trouble with this is that ddebugs* now points to someone elses memory, and we cant just steal it and stomp on the memory just in front of it (for the sites ptr). rename n to numdbgs Signed-off-by: Jim Cromie --- include/linux/dynamic_debug.h | 4 ++-- kernel/module-internal.h | 1 + kernel/module.c | 9 ++--- lib/dynamic_debug.c | 20 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index d811273c8484..7d33475d226a 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -70,8 +70,8 @@ struct _ddebug { /* exported for module authors to exercise >control */ int dynamic_debug_exec_queries(const char *query, const char *modname); -int ddebug_add_module(struct _ddebug *tab, unsigned int n, - const char *modname); +int ddebug_add_module(struct _ddebug *tab, struct _ddebug_site *sites, + unsigned int numdbgs, const char *modname); extern int ddebug_remove_module(const char *mod_name); extern __printf(2, 3) void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); diff --git a/kernel/module-internal.h b/kernel/module-internal.h index 33783abc377b..fb61eb2f8032 100644 --- a/kernel/module-internal.h +++ b/kernel/module-internal.h @@ -18,6 +18,7 @@ struct load_info { char *secstrings, *strtab; unsigned long symoffs, stroffs, init_typeoffs, core_typeoffs; struct _ddebug *debug; + struct _ddebug_site *sites; unsigned int num_debug; bool sig_ok; #ifdef CONFIG_KALLSYMS diff --git a/kernel/module.c b/kernel/module.c index 30479355ab85..792903230acd 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2780,11 +2780,12 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) } #endif /* CONFIG_KALLSYMS */ -static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsigned int num) +static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, + struct _ddebug_site *sites, unsigned int num) { if (!debug) return; - ddebug_add_module(debug, num, mod->name); + ddebug_add_module(debug, sites, num, mod->name); } static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug) @@ -,6 +3334,8 @@ static int find_module_sections(struct module *mod, struct load_info *info) info->debug = section_objs(info, "__dyndbg", sizeof(*info->debug), &info->num_debug); + info->sites = section_objs(info, "__dyndbg_sites", + sizeof(*info->sites), &info->num_debug); return 0; } @@ -4004,7 +4007,7 @@ static int load_module(struct load_info *info, const char __user *uargs, goto free_arch_cleanup; } - dynamic_debug_setup(mod, info->debug, info->num_debug); + dynamic_debug_setup(mod, info->debug, info->sites, info->num_debug); /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */ ftrace_module_init(mod); diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index fdc2d0e15731..be2e97ae2da9 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -49,6 +49,7 @@ struct ddebug_table { const char *mod_name; unsigned int num_ddebugs; struct _ddebug *ddebugs; + struct _ddebug_site *sites; }; struct ddebug_query { @@ -1014,14 +1015,14 @@ static const struct proc_ops proc_fops = { * Allocate a new ddebug_table for the given module * and add it to the global list. */ -int ddebug_add_module(struct _ddebug *tab, unsigned int n, -const char *name) +int ddebug_add_module(struct _ddebug *tab, struct _ddebug_site *sites, + unsigned int numdbgs, const char *modname) { struct ddebug_table *dt; dt = kzalloc(sizeof(*dt), GFP_KERNEL); if (dt == NULL) { - pr_err("error adding module: %s\n", name); + pr_err("error adding module: %s\n", modname); return -
[RFC PATCH v4 12/19] dyndbg: allow deleting site info via control interface
Allow users & subsystems to selectively delete callsite info for pr-debug callsites. Hopefully, this can lead to actual recovery of memory. DRM is a potential user which would drop the sites: - has distinct categories for logging, and can map them over to a format prefix, like: "drm:core:", "drm:kms:", etc. - are happy with group control of all the callsites in a class/cateory. individual control is still possible using queries including line numbers - don't need dynamic "module:function:line:" prefixes in log messages - don't care about loss of context in /proc/dynamic_debug/control before: init/initramfs.c:485 [initramfs]unpack_to_rootfs =_ "Detected %s compressed data\012" init/main.c:1337 [main]run_init_process =pm "%s\012" init/main.c:1335 [main]run_init_process =pm " with environment:\012" init/main.c:1334 [main]run_init_process =pm "%s\012" init/main.c:1332 [main]run_init_process =pm " with arguments:\012" init/main.c:1121 [main]initcall_blacklisted =pm "initcall %s blacklisted\012" init/main.c:1082 [main]initcall_blacklist =pm "blacklisting initcall %s\012" then: bash-5.0# echo file init/main.c +D > /proc/dynamic_debug/control after: init/initramfs.c:485 [initramfs]unpack_to_rootfs =_ "Detected %s compressed data\012" [main]:1337 =pmD "%s\012" [main]:1335 =pmD " with environment:\012" [main]:1334 =pmD "%s\012" [main]:1332 =pmD " with arguments:\012" [main]:1121 =pmD "initcall %s blacklisted\012" [main]:1082 =pmD "blacklisting initcall %s\012" Notes: If Drm adopted dyndbg, i915 + drm* would add ~1600 prdebugs, amdgpu + drm* would add ~3200 callsites, so the additional memory costs are substantial. In trade, drm and drivers would avoid lots of calls to drm_debug_enabled(). This patch should reduce the costs. Using this interface, drm could drop site info for all categories / prefixes controlled by bits in drm.debug, while preserving site info and individual selectivity for any uncategorized prdebugs, and for all other modules. Lastly, because lineno field was not moved into _ddebug_callsite, it can be used to modify a single[*] callsite even if drm has dropped all the callsite data: echo module $mod format ^$prefix line $line +p >control Dropping site info is a one-way, information losing operation, so minor misuse is possible. Worst case is maybe (depending upon previous settings) some loss of logging context/decorations. echo +D > /proc/dynamic_debug/control [*] amdgpu has some macros invoking clusters of pr_debugs; each use of them creates a cluster of pr-debugs with the same line number. Signed-off-by: Jim Cromie --- include/linux/dynamic_debug.h | 1 + lib/dynamic_debug.c | 9 + 2 files changed, 10 insertions(+) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index aa4a3f5d8d35..d811273c8484 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -40,6 +40,7 @@ struct _ddebug { #define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2) #define _DPRINTK_FLAGS_INCL_LINENO (1<<3) #define _DPRINTK_FLAGS_INCL_TID(1<<4) +#define _DPRINTK_FLAGS_DELETE_SITE (1<<7) /* drop site info to save ram */ #define _DPRINTK_FLAGS_INCL_ANYSITE\ (_DPRINTK_FLAGS_INCL_MODNAME\ diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 6fbd9099c2fa..fdc2d0e15731 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -92,6 +92,7 @@ static struct { unsigned flag:8; char opt_char; } opt_array[] = { { _DPRINTK_FLAGS_INCL_LINENO, 'l' }, { _DPRINTK_FLAGS_INCL_TID, 't' }, { _DPRINTK_FLAGS_NONE, '_' }, + { _DPRINTK_FLAGS_DELETE_SITE, 'D' }, }; struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; }; @@ -201,6 +202,14 @@ static void ddebug_alter_site(struct _ddebug *dp, } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT) static_branch_enable(&dp->key.dd_key_true); #endif + /* delete site info for this callsite */ + if (modifiers->flags & _DPRINTK_FLAGS_DELETE_SITE) { + if (dp->site) { + vpr_info("dropping site info %s.%s.%d\n", dp->site->filename, + dp->site->function, dp->lineno); + dp->site = NULL; + } + } } /* -- 2.29.2
[RFC PATCH v4 11/19] dyndbg: refactor ddebug_alter_site out of ddebug_change
Move the JUMP_LABEL/static-key code to a separate function. no functional changes. Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 2d011ac3308d..6fbd9099c2fa 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -191,6 +191,18 @@ static int ddebug_match_site(const struct ddebug_query *query, return true; } +static void ddebug_alter_site(struct _ddebug *dp, + struct flag_settings *modifiers) +{ +#ifdef CONFIG_JUMP_LABEL + if (dp->flags & _DPRINTK_FLAGS_PRINT) { + if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT)) + static_branch_disable(&dp->key.dd_key_true); + } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT) + static_branch_enable(&dp->key.dd_key_true); +#endif +} + /* * Search the tables for _ddebug's which match the given `query' and * apply the `flags' and `mask' to them. Returns number of matching @@ -227,13 +239,9 @@ static int ddebug_change(const struct ddebug_query *query, newflags = (dp->flags & modifiers->mask) | modifiers->flags; if (newflags == dp->flags) continue; -#ifdef CONFIG_JUMP_LABEL - if (dp->flags & _DPRINTK_FLAGS_PRINT) { - if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT)) - static_branch_disable(&dp->key.dd_key_true); - } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT) - static_branch_enable(&dp->key.dd_key_true); -#endif + + ddebug_alter_site(dp, modifiers); + dp->flags = newflags; if (dc) -- 2.29.2
[RFC PATCH v4 09/19] dyndbg: optimize ddebug_emit_prefix
Add early return if no callsite info is specified in site-flags. This avoids fetching site info that isn't going to be printed. Signed-off-by: Jim Cromie --- include/linux/dynamic_debug.h | 9 + lib/dynamic_debug.c | 3 +++ 2 files changed, 12 insertions(+) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index bc8027292c02..aa4a3f5d8d35 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -40,6 +40,15 @@ struct _ddebug { #define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2) #define _DPRINTK_FLAGS_INCL_LINENO (1<<3) #define _DPRINTK_FLAGS_INCL_TID(1<<4) + +#define _DPRINTK_FLAGS_INCL_ANYSITE\ + (_DPRINTK_FLAGS_INCL_MODNAME\ +| _DPRINTK_FLAGS_INCL_FUNCNAME \ +| _DPRINTK_FLAGS_INCL_LINENO) +#define _DPRINTK_FLAGS_INCL_ANY\ + (_DPRINTK_FLAGS_INCL_ANYSITE\ +| _DPRINTK_FLAGS_INCL_TID) + #if defined DEBUG #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT #else diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 1f0cac4a66af..af9cf97f869b 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -632,6 +632,9 @@ static char *dynamic_emit_prefix(const struct _ddebug *dp, char *buf) } pos_after_tid = pos; + if (!(dp->flags & _DPRINTK_FLAGS_INCL_ANYSITE)) + return buf; + if (desc) { if (dp->flags & _DPRINTK_FLAGS_INCL_MODNAME) pos += snprintf(buf + pos, remaining(pos), "%s:", -- 2.29.2
[RFC PATCH v4 10/19] dyndbg: avoid calling dyndbg_emit_prefix when it has no work
Wrap function in a static-inline one, which checks flags to avoid calling the function unnecessarily. Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index af9cf97f869b..2d011ac3308d 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -615,7 +615,7 @@ static int remaining(int wrote) return 0; } -static char *dynamic_emit_prefix(const struct _ddebug *dp, char *buf) +static char *__dynamic_emit_prefix(const struct _ddebug *dp, char *buf) { int pos_after_tid; int pos = 0; @@ -655,6 +655,13 @@ static char *dynamic_emit_prefix(const struct _ddebug *dp, char *buf) return buf; } +static inline char *dynamic_emit_prefix(struct _ddebug *dp, char *buf) +{ + if (unlikely(dp->flags & _DPRINTK_FLAGS_INCL_ANY)) + return __dynamic_emit_prefix(dp, buf); + return buf; +} + void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) { va_list args; -- 2.29.2
[PATCH 11/11] i2c: imx-lpi2c: add edma mode support
Add eDMA receive and send mode support. Support to read and write data larger than 256 bytes in one frame. Signed-off-by: Clark Wang Reviewed-by: Li Jun --- drivers/i2c/busses/i2c-imx-lpi2c.c | 291 - 1 file changed, 289 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 1e26672d47bf..6d920bf0dbd4 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -31,6 +33,7 @@ #define LPI2C_MCR 0x10/* i2c contrl register */ #define LPI2C_MSR 0x14/* i2c status register */ #define LPI2C_MIER 0x18/* i2c interrupt enable */ +#define LPI2C_MDER 0x1C/* i2c DMA enable */ #define LPI2C_MCFGR0 0x20/* i2c master configuration */ #define LPI2C_MCFGR1 0x24/* i2c master configuration */ #define LPI2C_MCFGR2 0x28/* i2c master configuration */ @@ -72,11 +75,15 @@ #define MCFGR1_AUTOSTOPBIT(8) #define MCFGR1_IGNACK BIT(9) #define MRDR_RXEMPTY BIT(14) +#define MDER_TDDE BIT(0) +#define MDER_RDDE BIT(1) #define I2C_CLK_RATIO 24 / 59 #define CHUNK_DATA 256 #define I2C_PM_TIMEOUT 1000 /* ms */ +#define I2C_DMA_THRESHOLD 16 /* bytes */ +#define I2C_USE_PIO(-150) enum lpi2c_imx_mode { STANDARD, /* <=100Kbps */ @@ -95,6 +102,7 @@ enum lpi2c_imx_pincfg { struct lpi2c_imx_struct { struct i2c_adapter adapter; + resource_size_t phy_addr; int irq; struct clk *clk_per; struct clk *clk_ipg; @@ -114,6 +122,17 @@ struct lpi2c_imx_struct { struct pinctrl *pinctrl; struct pinctrl_state *pinctrl_pins_default; struct pinctrl_state *pinctrl_pins_gpio; + + boolcan_use_dma; + boolusing_dma; + boolxferred; + struct i2c_msg *msg; + dma_addr_t dma_addr; + struct dma_chan *dma_tx; + struct dma_chan *dma_rx; + enum dma_data_direction dma_direction; + u8 *dma_buf; + unsigned intdma_len; }; static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx, @@ -289,6 +308,9 @@ static int lpi2c_imx_master_enable(struct lpi2c_imx_struct *lpi2c_imx) if (ret) goto rpm_put; + if (lpi2c_imx->can_use_dma) + writel(MDER_TDDE | MDER_RDDE, lpi2c_imx->base + LPI2C_MDER); + temp = readl(lpi2c_imx->base + LPI2C_MCR); temp |= MCR_MEN; writel(temp, lpi2c_imx->base + LPI2C_MCR); @@ -462,6 +484,154 @@ static void lpi2c_imx_read(struct lpi2c_imx_struct *lpi2c_imx, lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE | MIER_NDIE); } +static void lpi2c_dma_unmap(struct lpi2c_imx_struct *lpi2c_imx) +{ + struct dma_chan *chan = lpi2c_imx->dma_direction == DMA_FROM_DEVICE + ? lpi2c_imx->dma_rx : lpi2c_imx->dma_tx; + + dma_unmap_single(chan->device->dev, lpi2c_imx->dma_addr, +lpi2c_imx->dma_len, lpi2c_imx->dma_direction); + + lpi2c_imx->dma_direction = DMA_NONE; +} + +static void lpi2c_cleanup_dma(struct lpi2c_imx_struct *lpi2c_imx) +{ + if (lpi2c_imx->dma_direction == DMA_NONE) + return; + else if (lpi2c_imx->dma_direction == DMA_FROM_DEVICE) + dmaengine_terminate_all(lpi2c_imx->dma_rx); + else if (lpi2c_imx->dma_direction == DMA_TO_DEVICE) + dmaengine_terminate_all(lpi2c_imx->dma_tx); + + lpi2c_dma_unmap(lpi2c_imx); +} + +static void lpi2c_dma_callback(void *data) +{ + struct lpi2c_imx_struct *lpi2c_imx = (struct lpi2c_imx_struct *)data; + + lpi2c_dma_unmap(lpi2c_imx); + writel(GEN_STOP << 8, lpi2c_imx->base + LPI2C_MTDR); + lpi2c_imx->xferred = true; + + complete(&lpi2c_imx->complete); +} + +static int lpi2c_dma_submit(struct lpi2c_imx_struct *lpi2c_imx, + struct i2c_msg *msg) +{ + bool read = msg->flags & I2C_M_RD; + enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + struct dma_chan *chan = read ? lpi2c_imx->dma_rx : lpi2c_imx->dma_tx; + struct dma_async_tx_descriptor *txdesc; + dma_cookie_t cookie; + + lpi2c_imx->dma_len = read ? msg->len - 1 : msg->len; + lpi2c_imx->msg = msg; + lpi2c_imx->dma_direction = dir; + + if (IS_ERR(chan)) + return PTR_ERR(chan); + + lpi2c_imx->dma_addr = dma_map_single(chan->device->dev, +lpi2c_imx->dma_buf, +lpi2c_imx->dma_len, dir); + if (dma_mapping_error(chan->device->dev, lpi2c_imx->dma_addr)) { + dev_err(&l
[RFC PATCH v4 07/19] dyndbg: accept null site in dynamic_emit_prefix
2 prints use site->member, protect them with if site. no functional changes. Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 151e55ab6bb5..0c535f3c2ba9 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -631,15 +631,19 @@ static char *dynamic_emit_prefix(const struct _ddebug *dp, char *buf) task_pid_vnr(current)); } pos_after_tid = pos; - if (dp->flags & _DPRINTK_FLAGS_INCL_MODNAME) - pos += snprintf(buf + pos, remaining(pos), "%s:", - desc->modname); - if (dp->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) - pos += snprintf(buf + pos, remaining(pos), "%s:", - desc->function); + + if (desc) { + if (dp->flags & _DPRINTK_FLAGS_INCL_MODNAME) + pos += snprintf(buf + pos, remaining(pos), "%s:", + desc->modname); + if (dp->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) + pos += snprintf(buf + pos, remaining(pos), "%s:", + desc->function); + } if (dp->flags & _DPRINTK_FLAGS_INCL_LINENO) pos += snprintf(buf + pos, remaining(pos), "%d:", dp->lineno); + if (pos - pos_after_tid) pos += snprintf(buf + pos, remaining(pos), " "); if (pos >= PREFIX_SIZE) -- 2.29.2
[PATCH 10/11] i2c: imx-lpi2c: fix type char overflow issue when calculating the clock cycle
Claim clkhi and clklo as integer type to avoid possible calculation errors caused by data overflow. Reviewed-by: Fugang Duan Signed-off-by: Clark Wang --- drivers/i2c/busses/i2c-imx-lpi2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 5dbe85126f24..1e26672d47bf 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -213,8 +213,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx) CLKHI = I2C_CLK_RATIO * clk_cycle */ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) { - u8 prescale, filt, sethold, clkhi, clklo, datavd; - unsigned int clk_rate, clk_cycle; + u8 prescale, filt, sethold, datavd; + unsigned int clk_rate, clk_cycle, clkhi, clklo; enum lpi2c_imx_pincfg pincfg; unsigned int temp; -- 2.25.1
[RFC PATCH v4 04/19] dyndbg: accept null site in ddebug_match_site
basically, reorder the elements to minimize data fetches. 1- move format and line-number check code to the top of the function, since they don't use/check site info. 2- test site pointer: If its null, we return early, skipping 3: If the query tests against missing site info, fail the match. otherwize site matches. 3- rest of function (checking site vs query) is unchanged. ddebug_match_site ignores module, because it's tested already by the caller, where it is known from debug_tables. Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 41 + 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 9cff9db15937..da732e0c56e3 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -145,21 +145,7 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg) static int ddebug_match_site(const struct ddebug_query *query, const struct _ddebug *dp) { - struct _ddebug_site *dc = dp->site; - - /* match against the source filename */ - if (query->filename && - !match_wildcard(query->filename, dc->filename) && - !match_wildcard(query->filename, - kbasename(dc->filename)) && - !match_wildcard(query->filename, - trim_prefix(dc->filename))) - return false; - - /* match against the function */ - if (query->function && - !match_wildcard(query->function, dc->function)) - return false; + struct _ddebug_site *dc; /* match against the format */ if (query->format) { @@ -181,6 +167,29 @@ static int ddebug_match_site(const struct ddebug_query *query, dp->lineno > query->last_lineno) return false; + dc = dp->site; + if (!dc) { + /* site info has been dropped, so query cannot test these fields */ + if (query->filename || query->function) + return false; + else + return true; + } + + /* match against the source filename */ + if (query->filename && + !match_wildcard(query->filename, dc->filename) && + !match_wildcard(query->filename, + kbasename(dc->filename)) && + !match_wildcard(query->filename, + trim_prefix(dc->filename))) + return false; + + /* match against the function */ + if (query->function && + !match_wildcard(query->function, dc->function)) + return false; + return true; } @@ -210,7 +219,7 @@ static int ddebug_change(const struct ddebug_query *query, for (i = 0; i < dt->num_ddebugs; i++) { struct _ddebug *dp = &dt->ddebugs[i]; - struct _ddebug_site *dc = dp->site; + struct _ddebug_site *dc; if (!ddebug_match_site(query, dp)) continue; -- 2.29.2
[RFC PATCH v4 02/19] dyndbg: __init iterate over __dyndbg & __dyndbg_site in parallel
In dynamic_debug_init(), rework for-loop; add 2nd 'site' var, and iterate over both __dyndbg* sections in parallel. Replace uses of iter->site with the new 'site' iter, add a BUG_ON to enforce the invariant given by HEAD~1's DECLARE_DYNAMIC_DEBUG_METADATA base->site initialization. 0- declare the new elf section start/stop, named in vmlinux.lds.h I disregarded a checkpatch warning about externs in c-files, stuck with current practice. 1- clean up use of 4 iterators for clarity: (iter, site), and ((iter, site)_mod_start) block markers. 2- iterate over __dyndbg_sites in parallel with __dyndbg s/iter->site/site/g; 3- add BUG_ON(iter->site != site) DECLARE_DYNAMIC_DEBUG_METADATA + linker insure this now. Maybe we can drop pointer, still get order. 4- var rename n to site_ct Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 36 +++- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 738c4ce28046..c3c35dcc6a59 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -41,6 +41,8 @@ extern struct _ddebug __start___dyndbg[]; extern struct _ddebug __stop___dyndbg[]; +extern struct _ddebug_site __start___dyndbg_sites[]; +extern struct _ddebug_site __stop___dyndbg_sites[]; struct ddebug_table { struct list_head link; @@ -118,6 +120,7 @@ do { \ #define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__) #define v2pr_info(fmt, ...)vnpr_info(2, fmt, ##__VA_ARGS__) +#define v3pr_info(fmt, ...)vnpr_info(3, fmt, ##__VA_ARGS__) static void vpr_info_dq(const struct ddebug_query *query, const char *msg) { @@ -1082,11 +1085,12 @@ static int __init dynamic_debug_init_control(void) static int __init dynamic_debug_init(void) { - struct _ddebug *iter, *iter_start; + struct _ddebug *iter, *iter_mod_start; + struct _ddebug_site *site, *site_mod_start; const char *modname = NULL; char *cmdline; int ret = 0; - int n = 0, entries = 0, modct = 0; + int site_ct = 0, entries = 0, modct = 0; if (&__start___dyndbg == &__stop___dyndbg) { if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) { @@ -1097,23 +1101,29 @@ static int __init dynamic_debug_init(void) ddebug_init_success = 1; return 0; } - iter = __start___dyndbg; - modname = iter->site->modname; - iter_start = iter; - for (; iter < __stop___dyndbg; iter++) { + + iter = iter_mod_start = __start___dyndbg; + site = site_mod_start = __start___dyndbg_sites; + modname = site->modname; + + for (; iter < __stop___dyndbg; iter++, site++) { + + BUG_ON(site != iter->site); entries++; - if (strcmp(modname, iter->site->modname)) { + + if (strcmp(modname, site->modname)) { modct++; - ret = ddebug_add_module(iter_start, n, modname); + ret = ddebug_add_module(iter_mod_start, site_ct, modname); if (ret) goto out_err; - n = 0; - modname = iter->site->modname; - iter_start = iter; + site_ct = 0; + modname = site->modname; + iter_mod_start = iter; + site_mod_start = site; } - n++; + site_ct++; } - ret = ddebug_add_module(iter_start, n, modname); + ret = ddebug_add_module(iter_mod_start, site_ct, modname); if (ret) goto out_err; -- 2.29.2
[RFC PATCH v4 03/19] dyndbg: refactor part of ddebug_change to ddebug_match_site
Move all the site-match logic into a separate function, reindent the code, and replace the continues with return falses. No functional changes. Signed-off-by: Jim Cromie --- lib/dynamic_debug.c | 75 ++--- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index c3c35dcc6a59..9cff9db15937 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -142,6 +142,48 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg) query->first_lineno, query->last_lineno); } +static int ddebug_match_site(const struct ddebug_query *query, +const struct _ddebug *dp) +{ + struct _ddebug_site *dc = dp->site; + + /* match against the source filename */ + if (query->filename && + !match_wildcard(query->filename, dc->filename) && + !match_wildcard(query->filename, + kbasename(dc->filename)) && + !match_wildcard(query->filename, + trim_prefix(dc->filename))) + return false; + + /* match against the function */ + if (query->function && + !match_wildcard(query->function, dc->function)) + return false; + + /* match against the format */ + if (query->format) { + if (*query->format == '^') { + char *p; + /* anchored search. match must be at beginning */ + p = strstr(dp->format, query->format+1); + if (p != dp->format) + return false; + } else if (!strstr(dp->format, query->format)) + return false; + } + + /* match against the line number range */ + if (query->first_lineno && + dp->lineno < query->first_lineno) + return false; + if (query->last_lineno && + dp->lineno > query->last_lineno) + return false; + + return true; +} + /* * Search the tables for _ddebug's which match the given `query' and * apply the `flags' and `mask' to them. Returns number of matching @@ -170,38 +212,7 @@ static int ddebug_change(const struct ddebug_query *query, struct _ddebug *dp = &dt->ddebugs[i]; struct _ddebug_site *dc = dp->site; - /* match against the source filename */ - if (query->filename && - !match_wildcard(query->filename, dc->filename) && - !match_wildcard(query->filename, - kbasename(dc->filename)) && - !match_wildcard(query->filename, - trim_prefix(dc->filename))) - continue; - - /* match against the function */ - if (query->function && - !match_wildcard(query->function, dc->function)) - continue; - - /* match against the format */ - if (query->format) { - if (*query->format == '^') { - char *p; - /* anchored search. match must be at beginning */ - p = strstr(dp->format, query->format+1); - if (p != dp->format) - continue; - } else if (!strstr(dp->format, query->format)) - continue; - } - - /* match against the line number range */ - if (query->first_lineno && - dp->lineno < query->first_lineno) - continue; - if (query->last_lineno && - dp->lineno > query->last_lineno) + if (!ddebug_match_site(query, dp)) continue; nfound++; -- 2.29.2
[PATCH 09/11] i2c: imx-lpi2c: fix i2c timing issue
The clkhi and clklo ratio was not very precise before that can make the time of START/STOP/HIGH LEVEL out of specification. Therefore, the calculation of these times has been modified in this patch. At the same time, the mode rate definition of i2c is corrected. Reviewed-by: Fugang Duan Signed-off-by: Clark Wang --- drivers/i2c/busses/i2c-imx-lpi2c.c | 27 ++- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 7216a393095d..5dbe85126f24 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -73,17 +73,17 @@ #define MCFGR1_IGNACK BIT(9) #define MRDR_RXEMPTY BIT(14) -#define I2C_CLK_RATIO 2 +#define I2C_CLK_RATIO 24 / 59 #define CHUNK_DATA 256 #define I2C_PM_TIMEOUT 1000 /* ms */ enum lpi2c_imx_mode { - STANDARD, /* 100+Kbps */ - FAST, /* 400+Kbps */ - FAST_PLUS, /* 1.0+Mbps */ - HS, /* 3.4+Mbps */ - ULTRA_FAST, /* 5.0+Mbps */ + STANDARD, /* <=100Kbps */ + FAST, /* <=400Kbps */ + FAST_PLUS, /* <=1.0Mbps */ + HS, /* <=3.4Mbps */ + ULTRA_FAST, /* <=5.0Mbps */ }; enum lpi2c_imx_pincfg { @@ -156,13 +156,13 @@ static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx) unsigned int bitrate = lpi2c_imx->bitrate; enum lpi2c_imx_mode mode; - if (bitrate < I2C_MAX_FAST_MODE_FREQ) + if (bitrate <= I2C_MAX_STANDARD_MODE_FREQ) mode = STANDARD; - else if (bitrate < I2C_MAX_FAST_MODE_PLUS_FREQ) + else if (bitrate <= I2C_MAX_FAST_MODE_FREQ) mode = FAST; - else if (bitrate < I2C_MAX_HIGH_SPEED_MODE_FREQ) + else if (bitrate <= I2C_MAX_FAST_MODE_PLUS_FREQ) mode = FAST_PLUS; - else if (bitrate < I2C_MAX_ULTRA_FAST_MODE_FREQ) + else if (bitrate <= I2C_MAX_HIGH_SPEED_MODE_FREQ) mode = HS; else mode = ULTRA_FAST; @@ -209,7 +209,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx) } while (1); } -/* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */ +/* CLKLO = (1 - I2C_CLK_RATIO) * clk_cycle, SETHOLD = CLKHI, DATAVD = CLKHI/2 + CLKHI = I2C_CLK_RATIO * clk_cycle */ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) { u8 prescale, filt, sethold, clkhi, clklo, datavd; @@ -232,8 +233,8 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) for (prescale = 0; prescale <= 7; prescale++) { clk_cycle = clk_rate / ((1 << prescale) * lpi2c_imx->bitrate) - - 3 - (filt >> 1); - clkhi = (clk_cycle + I2C_CLK_RATIO) / (I2C_CLK_RATIO + 1); + - (2 + filt) / (1 << prescale); + clkhi = clk_cycle * I2C_CLK_RATIO; clklo = clk_cycle - clkhi; if (clklo < 64) break; -- 2.25.1
[RFC PATCH v4 00/19] dynamic debug diet plan
v4 fixes 'series grooming errors', Reported-by: kernel test robot CONFIG_DYNAMIC_DEBUG creates a struct _ddebug (56 bytes) for each callsite, which includes 3 pointers to: module, filename, function. These are repetetive, and compressible, this patch series goes about doing that, it: - splits struct _ddebug and __dyndbg[] section/array into 2 creating struct _ddebug_site and __dyndbg_sites[] temporary _ddebug.site connects them. - makes _ddebug_site data optional - minor optimizations - makes _ddebug_site data deleteable not necessary, proof of optionality The RFC stuff comes at the end: - attach __dyndbg_sites[] to module-info, like __dyndbg[] - add index to struct _ddebug, use it for builtins - add ddebug_site(_get|_put) abstraction to hide _ddebug.site At this point, its practical to: compress __dyndbg_sites[] & replace the section, then expand it on-demand to serve ddebug_site_get() calls. For enabled callsites (with decorations flags), the retrieved records can be cached in a hash after theyre 1st needed/used (when callsite is actually executed). Whats my (ideal?) decompressing interface ? And whats the name of the api call ? I couldnt suss it out yet. For any control read, a simple block decompress and cache is close to ideal; all site data is then available to iterate over, and each ddebug_site_get() just indexes into it. A stream of decompressed site records would also work well, with less lumpy memory allocs and frees. Actually dropping _ddebug.site is not yet possible. While we could drop it for builtin modules, thats cuz we know __start___dyndbg_sites. For loaded modules, I need the elf section: __dyndbg_sites. This is in load-info, but I dont have a path to it. In: - add _ddebug_header/table That adds a single header entry pair (structs _ddebug*s with special initialization) into the arrays, and it links to the front of the array, where its useful. But creating this header entry only works for vmlinux itself (because of vmlinux.ld.h patch), not for loadable modules. - add linker rules to module.lds.h I tried to re-use the DYMAMIC_DEBUG_DATA macro added above for modules, this failed, commit msg guesses the cause. This breaks with a linker script syntax error TODO Presuming the fixed header can be linked reliably in front doing something like I tried, it can be recast as a ddebug_header and unionized with struct _ddebug, and the _ddebugs[] will fit nicely as a flex-array: struct ddebug_table2 { struct ddebug_header foo; struct _ddebug ddebugs[]; } A header would have 40 bytes, room to contain most/all of struct ddebug_table's fields, a pointer to the __dyndbg_sites[] table, and a list-head too, meaning it supports essential and nice-to-have properties: - the mapping: __dyndbg[N] --> __dyndbg_sites[N] # NEEDed to drop .site using container_of_flex() for flex-arrays - we can add them directly to ddebug_tables list # freebie ie avoid the kzalloc in ddebug_add_module() If not all fields fit in the space available in __dyndbg[0], there is space available in __dyndbg_sites[0]. Additionally, at the end of __init, ddebug_tables list is composed of memory entirely in __dyndbg[], which could then be make readonly (by means I dont know). If this breaks insertions of loadable modules, we can easily a 2nd list for that. Jim Cromie (19): dyndbg: split struct _ddebug, move display fields to new _ddebug_site dyndbg: __init iterate over __dyndbg & __dyndbg_site in parallel dyndbg: refactor part of ddebug_change to ddebug_match_site dyndbg: accept null site in ddebug_match_site dyndbg: hoist ->site out of ddebug_match_site dyndbg: accept null site in ddebug_change dyndbg: accept null site in dynamic_emit_prefix dyndbg: accept null site in ddebug_proc_show dyndbg: optimize ddebug_emit_prefix dyndbg: avoid calling dyndbg_emit_prefix when it has no work dyndbg: refactor ddebug_alter_site out of ddebug_change dyndbg: allow deleting site info via control interface dyndbg+module: expose ddebug_sites to modules dyndbg: add ddebug_site(_get|_put) abstraction dyndbg: add _index to struct _ddebug dyndbg: prevent build bugs via -DNO_DYNAMIC_DEBUG_TABLE dyndbg: RFC - DECLARE/DEFINE_DYNAMIC_DEBUG_TABLE dyndbg: shuffle ddebug_table fields dyndbg: RFC add linker rules to module.lds.h arch/x86/boot/compressed/Makefile | 1 + arch/x86/entry/vdso/Makefile | 3 + arch/x86/purgatory/Makefile | 1 + drivers/firmware/efi/libstub/Makefile | 3 +- drivers/gpu/drm/i915/i915_drv.c | 2 + include/asm-generic/module.lds.h | 21 ++ include/asm-generic/vmlinux.lds.h | 24 +- include/linux/dynamic_debug.h | 180 +-- kernel/module-internal.h | 1 + kernel/module.c | 9 +- lib/dynamic_debug.c | 313 +++--- scripts/Makefile.lib | 2 + 12 files changed, 449 insertions(+)
[RFC PATCH v4 01/19] dyndbg: split struct _ddebug, move display fields to new _ddebug_site
struct _ddebug has 2 flavors of fields: essential and optional. Split the 3 optional fields: module, function, file into a new struct _ddebug_site, and add pointer to it from _ddebug. These fields are optional in that they are primarily used to generate the optional "module:func:line" log prefix. They're also used to select callsites to >control. lineno is arguably optional too, but leaving it uses spare bytes in struct _ddebug. The new ptr increases memory footprint by 1 ptr per pr_debug, but I think its temporary, and the indirection gives several advantages: - we can drop sites and their storage opportunistically. this reduces per-site mem by 24/64. Subsystems may not need/want "module:func:line:" in their logs. If they already use format-prefixes such as "drm:kms:", they can select on those, and don't need the site info for that. forex: #> echo module drm format "^drm:kms: " +p >control ie: dynamic_debug_exec_queries("format '^drm:kms: '", "drm"); - the moved display fields are inherently hierarchical, and the linker section is ordered; so (module, file, function) have repeating values (90%, 85%, 45%). This is readily compressible, even with a simple field-wise run length encoding. Since I'm splitting the struct, I also reordered the fields to match the hierarchy. - the separate linker section sets up naturally for block compression. IFF we can on-demand map: ddebugs[N] -> ddebug_sites[N] - we can compress __dyndbg_sites during __init, and mark section __initdata - can decompress on-demand, say for `cat control` - can save chunks of decompressed buffer for enabled callsites - free chunks on site disable, or on memory pressure. Whats actually done here is rather mechanical, and preparatory. dynamic_debug.h: I cut struct _ddebug in half, renamed optional top-half to _ddebug_site, kept __align(8) for both halves. I added a forward decl for a unified comment for both head & body, and added head.site to point at body. DECLARE_DYNAMIC_DEBUG_METADATA does the core of the work; it declares and initializes both static struct variables together, and refs one to the other. dynamic_debug.c: dynamic_debug_init() mem-usage now also counts sites. dynamic_emit_prefix() & ddebug_change() use those moved fields; they get a new initialized auto-var, and the field refs get adjusted as needed to follow the move from one struct to the other. struct _ddebug_site *dc = dp->site; ddebug_proc_show() differs slightly; it assigns to (not initializes) the autovar, to avoid a panic when p == SEQ_START_TOKEN. vmlinux.lds.h: add __dyndbg_sites section, with the same align(8) and KEEP as used in the __dyndbg section. Signed-off-by: Jim Cromie --- include/asm-generic/vmlinux.lds.h | 3 ++ include/linux/dynamic_debug.h | 37 - lib/dynamic_debug.c | 46 +-- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 0331d5d49551..4f2af9de2f03 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -353,6 +353,9 @@ *(__tracepoints)\ /* implement dynamic printk debug */\ . = ALIGN(8); \ + __start___dyndbg_sites = .; \ + KEEP(*(__dyndbg_sites)) \ + __stop___dyndbg_sites = .; \ __start___dyndbg = .; \ KEEP(*(__dyndbg)) \ __stop___dyndbg = .;\ diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index a57ee75342cf..bc8027292c02 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -7,20 +7,28 @@ #endif /* - * An instance of this structure is created in a special - * ELF section at every dynamic debug callsite. At runtime, - * the special section is treated as an array of these. + * A pair of these structs are created in 2 special ELF sections + * (__dyndbg, __dyndbg_sites) for every dynamic debug callsite. + * At runtime, the sections are treated as arrays. */ -struct _ddebug { +struct _ddebug; +struct _ddebug_site { /* -* These fields are used to drive the user interface -* for selecting and displaying debug callsites. +* These fields (and lineno) are used to: +* - decorate log messages per site flags +* - select callsites for modification via >control +* - display callsites & settings in `cat control` */ const char *modname; - const char *function; const char *filename; + const char *function; +} __aligned(8); + +struct _ddebug { +
[PATCH 08/11] i2c: imx-lpi2c: add bus recovery feature
Add bus recovery feature for LPI2C. Need add gpio pinctrl, scl-gpios and sda-gpios configuration in dts. Signed-off-by: Clark Wang --- drivers/i2c/busses/i2c-imx-lpi2c.c | 83 ++ 1 file changed, 83 insertions(+) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index c0cb77c66090..7216a393095d 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,11 @@ struct lpi2c_imx_struct { unsigned inttxfifosize; unsigned intrxfifosize; enum lpi2c_imx_mode mode; + + struct i2c_bus_recovery_info rinfo; + struct pinctrl *pinctrl; + struct pinctrl_state *pinctrl_pins_default; + struct pinctrl_state *pinctrl_pins_gpio; }; static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx, @@ -135,6 +141,8 @@ static int lpi2c_imx_bus_busy(struct lpi2c_imx_struct *lpi2c_imx) if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n"); + if (lpi2c_imx->adapter.bus_recovery_info) + i2c_recover_bus(&lpi2c_imx->adapter); return -ETIMEDOUT; } schedule(); @@ -192,6 +200,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx) if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { dev_dbg(&lpi2c_imx->adapter.dev, "stop timeout\n"); + if (lpi2c_imx->adapter.bus_recovery_info) + i2c_recover_bus(&lpi2c_imx->adapter); break; } schedule(); @@ -329,6 +339,8 @@ static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx) if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { dev_dbg(&lpi2c_imx->adapter.dev, "txfifo empty timeout\n"); + if (lpi2c_imx->adapter.bus_recovery_info) + i2c_recover_bus(&lpi2c_imx->adapter); return -ETIMEDOUT; } schedule(); @@ -528,6 +540,71 @@ static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static void lpi2c_imx_prepare_recovery(struct i2c_adapter *adap) +{ + struct lpi2c_imx_struct *lpi2c_imx; + + lpi2c_imx = container_of(adap, struct lpi2c_imx_struct, adapter); + + pinctrl_select_state(lpi2c_imx->pinctrl, lpi2c_imx->pinctrl_pins_gpio); +} + +static void lpi2c_imx_unprepare_recovery(struct i2c_adapter *adap) +{ + struct lpi2c_imx_struct *lpi2c_imx; + + lpi2c_imx = container_of(adap, struct lpi2c_imx_struct, adapter); + + pinctrl_select_state(lpi2c_imx->pinctrl, lpi2c_imx->pinctrl_pins_default); +} + +/* + * We switch SCL and SDA to their GPIO function and do some bitbanging + * for bus recovery. These alternative pinmux settings can be + * described in the device tree by a separate pinctrl state "gpio". If + * this is missing this is not a big problem, the only implication is + * that we can't do bus recovery. + */ +static int lpi2c_imx_init_recovery_info(struct lpi2c_imx_struct *lpi2c_imx, + struct platform_device *pdev) +{ + struct i2c_bus_recovery_info *rinfo = &lpi2c_imx->rinfo; + + lpi2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev); + if (!lpi2c_imx->pinctrl || IS_ERR(lpi2c_imx->pinctrl)) { + dev_info(&pdev->dev, "can't get pinctrl, bus recovery not supported\n"); + return PTR_ERR(lpi2c_imx->pinctrl); + } + + lpi2c_imx->pinctrl_pins_default = pinctrl_lookup_state(lpi2c_imx->pinctrl, + PINCTRL_STATE_DEFAULT); + lpi2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(lpi2c_imx->pinctrl, + "gpio"); + rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN); + rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN); + + if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER || + PTR_ERR(rinfo->scl_gpiod) == -EPROBE_DEFER) { + return -EPROBE_DEFER; + } else if (IS_ERR(rinfo->sda_gpiod) || + IS_ERR(rinfo->scl_gpiod) || + IS_ERR(lpi2c_imx->pinctrl_pins_default) || + IS_ERR(lpi2c_imx->pinctrl_pins_gpio)) { + dev_dbg(&pdev->dev, "recovery information incomplete\n"); + return 0; + } + + dev_info(&pdev->dev, "using scl%s for recovery\n", +rinfo->sda_gpiod ? ",sda" : ""); + + rinfo->prepare_recovery = lpi2c_imx_prepare_recovery; + rinfo->unprepare_recovery = lpi2c_imx_unprepare_recovery; + rinfo->recover_bu
[PATCH 07/11] i2c: imx-lpi2c: increase PM timeout to avoid operate clk frequently
Switching the clock frequently will affect the data transmission efficiency, and prolong the timeout to reduce autosuspend times for lpi2c. Acked-by: Fugang Duan Signed-off-by: Clark Wang --- drivers/i2c/busses/i2c-imx-lpi2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 86b69852f7be..c0cb77c66090 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -75,7 +75,7 @@ #define I2C_CLK_RATIO 2 #define CHUNK_DATA 256 -#define I2C_PM_TIMEOUT 10 /* ms */ +#define I2C_PM_TIMEOUT 1000 /* ms */ enum lpi2c_imx_mode { STANDARD, /* 100+Kbps */ -- 2.25.1
[PATCH 04/11] i2c: imx-lpi2c: manage irq resource request/release in runtime pm
From: Fugang Duan Manage irq resource request/release in runtime pm to save irq domain's power. Signed-off-by: Frank Li Signed-off-by: Fugang Duan Reviewed-by: Frank Li --- drivers/i2c/busses/i2c-imx-lpi2c.c | 26 ++ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 664fcc0dba51..e718bb6b2387 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -94,6 +94,7 @@ enum lpi2c_imx_pincfg { struct lpi2c_imx_struct { struct i2c_adapter adapter; + int irq; struct clk *clk_per; struct clk *clk_ipg; void __iomem*base; @@ -543,7 +544,7 @@ static int lpi2c_imx_probe(struct platform_device *pdev) { struct lpi2c_imx_struct *lpi2c_imx; unsigned int temp; - int irq, ret; + int ret; lpi2c_imx = devm_kzalloc(&pdev->dev, sizeof(*lpi2c_imx), GFP_KERNEL); if (!lpi2c_imx) @@ -553,9 +554,9 @@ static int lpi2c_imx_probe(struct platform_device *pdev) if (IS_ERR(lpi2c_imx->base)) return PTR_ERR(lpi2c_imx->base); - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; + lpi2c_imx->irq = platform_get_irq(pdev, 0); + if (lpi2c_imx->irq < 0) + return lpi2c_imx->irq; lpi2c_imx->adapter.owner= THIS_MODULE; lpi2c_imx->adapter.algo = &lpi2c_imx_algo; @@ -581,14 +582,6 @@ static int lpi2c_imx_probe(struct platform_device *pdev) if (ret) lpi2c_imx->bitrate = I2C_MAX_STANDARD_MODE_FREQ; - ret = devm_request_irq(&pdev->dev, irq, lpi2c_imx_isr, - IRQF_NO_SUSPEND, - pdev->name, lpi2c_imx); - if (ret) { - dev_err(&pdev->dev, "can't claim irq %d\n", irq); - return ret; - } - i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx); platform_set_drvdata(pdev, lpi2c_imx); @@ -640,6 +633,7 @@ static int __maybe_unused lpi2c_runtime_suspend(struct device *dev) { struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); + devm_free_irq(dev, lpi2c_imx->irq, lpi2c_imx); clk_disable_unprepare(lpi2c_imx->clk_ipg); clk_disable_unprepare(lpi2c_imx->clk_per); pinctrl_pm_select_idle_state(dev); @@ -665,6 +659,14 @@ static int __maybe_unused lpi2c_runtime_resume(struct device *dev) dev_err(dev, "can't enable I2C ipg clock, ret=%d\n", ret); } + ret = devm_request_irq(dev, lpi2c_imx->irq, lpi2c_imx_isr, + IRQF_NO_SUSPEND, + dev_name(dev), lpi2c_imx); + if (ret) { + dev_err(dev, "can't claim irq %d\n", lpi2c_imx->irq); + return ret; + } + return ret; } -- 2.25.1
[PATCH 06/11] i2c: imx-lpi2c: improve i2c driver probe priority
From: Gao Pan use subsys_initcall for i2c driver to improve i2c driver probe priority Signed-off-by: Gao Pan --- drivers/i2c/busses/i2c-imx-lpi2c.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 8f9dd3dd2951..86b69852f7be 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -710,7 +710,17 @@ static struct platform_driver lpi2c_imx_driver = { }, }; -module_platform_driver(lpi2c_imx_driver); +static int __init lpi2c_imx_init(void) +{ + return platform_driver_register(&lpi2c_imx_driver); +} +subsys_initcall(lpi2c_imx_init); + +static void __exit lpi2c_imx_exit(void) +{ + platform_driver_unregister(&lpi2c_imx_driver); +} +module_exit(lpi2c_imx_exit); MODULE_AUTHOR("Gao Pan "); MODULE_DESCRIPTION("I2C adapter driver for LPI2C bus"); -- 2.25.1
[PATCH 05/11] i2c: imx-lpi2c: add debug message when i2c peripheral clk doesn't work
From: Gao Pan add debug message when i2c peripheral clk rate is 0, then directly return -EINVAL. Signed-off-by: Gao Pan Reviewed-by: Andy Duan --- drivers/i2c/busses/i2c-imx-lpi2c.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index e718bb6b2387..8f9dd3dd2951 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -209,7 +209,12 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) lpi2c_imx_set_mode(lpi2c_imx); - clk_rate = clk_get_rate(lpi2c_imx->clk); + clk_rate = clk_get_rate(lpi2c_imx->clk_per); + if (!clk_rate) { + dev_dbg(&lpi2c_imx->adapter.dev, "clk_per rate is 0\n"); + return -EINVAL; + } + if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST) filt = 0; else -- 2.25.1
[PATCH 02/11] i2c: imx-lpi2c: add runtime pm support
From: Fugang Duan - Add runtime pm support to dynamicly manage the clock. - Put the suspend to suspend_noirq. - Call .pm_runtime_force_suspend() to force runtime pm suspended in .suspend_noirq(). Signed-off-by: Fugang Duan Signed-off-by: Gao Pan Reviewed-by: Anson Huang --- drivers/i2c/busses/i2c-imx-lpi2c.c | 50 -- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index bbf44ac95021..1e920e7ac7c1 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -574,7 +574,8 @@ static int lpi2c_imx_probe(struct platform_device *pdev) if (ret) lpi2c_imx->bitrate = I2C_MAX_STANDARD_MODE_FREQ; - ret = devm_request_irq(&pdev->dev, irq, lpi2c_imx_isr, 0, + ret = devm_request_irq(&pdev->dev, irq, lpi2c_imx_isr, + IRQF_NO_SUSPEND, pdev->name, lpi2c_imx); if (ret) { dev_err(&pdev->dev, "can't claim irq %d\n", irq); @@ -584,35 +585,32 @@ static int lpi2c_imx_probe(struct platform_device *pdev) i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx); platform_set_drvdata(pdev, lpi2c_imx); - ret = clk_prepare_enable(lpi2c_imx->clk); - if (ret) { - dev_err(&pdev->dev, "clk enable failed %d\n", ret); - return ret; - } - pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_get_noresume(&pdev->dev); - pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&pdev->dev); + dev_err(&pdev->dev, "failed to enable clock\n"); + return ret; + } + temp = readl(lpi2c_imx->base + LPI2C_PARAM); lpi2c_imx->txfifosize = 1 << (temp & 0x0f); lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f); + pm_runtime_put(&pdev->dev); + ret = i2c_add_adapter(&lpi2c_imx->adapter); if (ret) goto rpm_disable; - pm_runtime_mark_last_busy(&pdev->dev); - pm_runtime_put_autosuspend(&pdev->dev); - dev_info(&lpi2c_imx->adapter.dev, "LPI2C adapter registered\n"); return 0; rpm_disable: - pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); @@ -636,7 +634,7 @@ static int __maybe_unused lpi2c_runtime_suspend(struct device *dev) struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); clk_disable_unprepare(lpi2c_imx->clk); - pinctrl_pm_select_sleep_state(dev); + pinctrl_pm_select_idle_state(dev); return 0; } @@ -649,16 +647,34 @@ static int __maybe_unused lpi2c_runtime_resume(struct device *dev) pinctrl_pm_select_default_state(dev); ret = clk_prepare_enable(lpi2c_imx->clk); if (ret) { - dev_err(dev, "failed to enable I2C clock, ret=%d\n", ret); + dev_err(dev, "can't enable I2C clock, ret=%d\n", ret); return ret; } + return ret; +} + +static int lpi2c_suspend_noirq(struct device *dev) +{ + int ret; + + ret = pm_runtime_force_suspend(dev); + if (ret) + return ret; + + pinctrl_pm_select_sleep_state(dev); + return 0; } +static int lpi2c_resume_noirq(struct device *dev) +{ + return pm_runtime_force_resume(dev); +} + static const struct dev_pm_ops lpi2c_pm_ops = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(lpi2c_suspend_noirq, +lpi2c_resume_noirq) SET_RUNTIME_PM_OPS(lpi2c_runtime_suspend, lpi2c_runtime_resume, NULL) }; -- 2.25.1
[PATCH 01/11] i2c: imx-lpi2c: directly retrun ISR when detect a NACK
From: Gao Pan A NACK flag in ISR means i2c bus error. In such codition, there is no need to do read/write operation. It's better to return ISR directly and then stop i2c transfer. Signed-off-by: Gao Pan Signed-off-by: Clark Wang --- drivers/i2c/busses/i2c-imx-lpi2c.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 9db6ccded5e9..bbf44ac95021 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -507,15 +507,17 @@ static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id) lpi2c_imx_intctrl(lpi2c_imx, 0); temp = readl(lpi2c_imx->base + LPI2C_MSR); + if (temp & MSR_NDF) { + complete(&lpi2c_imx->complete); + goto ret; + } + if (temp & MSR_RDF) lpi2c_imx_read_rxfifo(lpi2c_imx); - - if (temp & MSR_TDF) + else if (temp & MSR_TDF) lpi2c_imx_write_txfifo(lpi2c_imx); - if (temp & MSR_NDF) - complete(&lpi2c_imx->complete); - +ret: return IRQ_HANDLED; } -- 2.25.1
[PATCH 03/11] i2c: imx-lpi2c: add ipg clk for lpi2c driver
The lpi2c IP needs two clks: ipg clk and per clk. The old lpi2c driver missed ipg clk. This patch adds ipg clk for lpi2c driver. Signed-off-by: Gao Pan Signed-off-by: Clark Wang Acked-by: Fugang Duan --- drivers/i2c/busses/i2c-imx-lpi2c.c | 28 +--- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 1e920e7ac7c1..664fcc0dba51 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -94,7 +94,8 @@ enum lpi2c_imx_pincfg { struct lpi2c_imx_struct { struct i2c_adapter adapter; - struct clk *clk; + struct clk *clk_per; + struct clk *clk_ipg; void __iomem*base; __u8*rx_buf; __u8*tx_buf; @@ -563,10 +564,16 @@ static int lpi2c_imx_probe(struct platform_device *pdev) strlcpy(lpi2c_imx->adapter.name, pdev->name, sizeof(lpi2c_imx->adapter.name)); - lpi2c_imx->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(lpi2c_imx->clk)) { + lpi2c_imx->clk_per = devm_clk_get(&pdev->dev, "per"); + if (IS_ERR(lpi2c_imx->clk_per)) { dev_err(&pdev->dev, "can't get I2C peripheral clock\n"); - return PTR_ERR(lpi2c_imx->clk); + return PTR_ERR(lpi2c_imx->clk_per); + } + + lpi2c_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); + if (IS_ERR(lpi2c_imx->clk_ipg)) { + dev_err(&pdev->dev, "can't get I2C ipg clock\n"); + return PTR_ERR(lpi2c_imx->clk_ipg); } ret = of_property_read_u32(pdev->dev.of_node, @@ -633,7 +640,8 @@ static int __maybe_unused lpi2c_runtime_suspend(struct device *dev) { struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); - clk_disable_unprepare(lpi2c_imx->clk); + clk_disable_unprepare(lpi2c_imx->clk_ipg); + clk_disable_unprepare(lpi2c_imx->clk_per); pinctrl_pm_select_idle_state(dev); return 0; @@ -645,12 +653,18 @@ static int __maybe_unused lpi2c_runtime_resume(struct device *dev) int ret; pinctrl_pm_select_default_state(dev); - ret = clk_prepare_enable(lpi2c_imx->clk); + ret = clk_prepare_enable(lpi2c_imx->clk_per); if (ret) { - dev_err(dev, "can't enable I2C clock, ret=%d\n", ret); + dev_err(dev, "can't enable I2C per clock, ret=%d\n", ret); return ret; } + ret = clk_prepare_enable(lpi2c_imx->clk_ipg); + if (ret) { + clk_disable_unprepare(lpi2c_imx->clk_per); + dev_err(dev, "can't enable I2C ipg clock, ret=%d\n", ret); + } + return ret; } -- 2.25.1
[PATCH 00/11] i2c: imx-lpi2c: New features and bug fixes
Hi, Here are some patches to add some new features and bug fixes/improvements. Each patch of these 11 patches is made on the basis of the previous patches. New features: - add bus recovery support - add edma mode support - add runtime pm support Improvements: - increase PM timeout to avoid operate clk frequently - manage irq resource request/release in runtime pm - directly retrun ISR when detect a NACK - improve i2c driver probe priority - add debug message Bug fixes: - fix i2c timing issue - fix type char overflow issue when calculating the clock cycle - add the missing ipg clk Best Regards, Clark Wang drivers/i2c/busses/i2c-imx-lpi2c.c | 536 + 1 file changed, 478 insertions(+), 58 deletions(-) -- 2.25.1
[PATCH 2/2] Fix spelling typo
From: ganjisheng Signed-off-by: ganjisheng --- drivers/mfd/88pm800.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index c7f9649..4ffd9d2 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -285,10 +285,10 @@ static int device_gpadc_init(struct pm80x_chip *chip, goto out; /* -* the defult of PM800 is GPADC operates at 100Ks/s rate +* the default of PM800 is GPADC operates at 100Ks/s rate * and Number of GPADC slots with active current bias prior * to GPADC sampling = 1 slot for all GPADCs set for -* Temprature mesurmants +* Temperature measurements */ mask = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN1 | PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3); -- 1.9.1
[PATCH v4 1/2] dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller
Add documentation for Versal DWC3 controller. Add required property 'reg' for the same. Also add optional properties for snps,dwc3. Signed-off-by: Manish Narani Reviewed-by: Rob Herring --- .../devicetree/bindings/usb/dwc3-xilinx.txt| 28 -- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index a668f43..04813a4 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -1,32 +1,56 @@ Xilinx SuperSpeed DWC3 USB SoC controller Required properties: -- compatible: Should contain "xlnx,zynqmp-dwc3" +- compatible: May contain "xlnx,zynqmp-dwc3" or "xlnx,versal-dwc3" +- reg: Base address and length of the register control block - clocks: A list of phandles for the clocks listed in clock-names - clock-names: Should contain the following: "bus_clk" Master/Core clock, have to be >= 125 MHz for SS operation and >= 60MHz for HS operation "ref_clk" Clock source to core during PHY power down +- resets: A list of phandles for resets listed in reset-names +- reset-names: + "usb_crst"USB core reset + "usb_hibrst" USB hibernation reset + "usb_apbrst" USB APB reset Required child node: A child node must exist to represent the core DWC3 IP block. The name of the node is not important. The content of the node is defined in dwc3.txt. +Optional properties for snps,dwc3: +- dma-coherent:Enable this flag if CCI is enabled in design. Adding this + flag configures Global SoC bus Configuration Register and + Xilinx USB 3.0 IP - USB coherency register to enable CCI. +- interrupt-names: Should contain the following: + "dwc_usb3" USB gadget mode interrupts + "otg"USB OTG mode interrupts + "hiber" USB hibernation interrupts + Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; compatible = "xlnx,zynqmp-dwc3"; + reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk", "ref_clk"; clocks = <&clk125>, <&clk125>; + resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>, +<&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>, +<&zynqmp_reset ZYNQMP_RESET_USB1_APB>; + reset-names = "usb_crst", "usb_hibrst", "usb_apbrst"; ranges; dwc3@fe20 { compatible = "snps,dwc3"; reg = <0x0 0xfe20 0x4>; - interrupts = <0x0 0x41 0x4>; + interrupt-names = "dwc_usb3", "otg", "hiber"; + interrupts = <0 65 4>, <0 69 4>, <0 75 4>; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + phy-names = "usb3-phy"; dr_mode = "host"; + dma-coherent; }; }; -- 2.1.1
Re: [PATCH] staging: comedi: das800: fix request_irq() warn
On Wed, Mar 17, 2021 at 01:55:40AM -0400, Tong Zhang wrote: > Thanks for pointing that out. > Yes you are right there is a mistake. > I am a human. Human make mistakes. Therefore I make mistakes. > Yep. We all make mistakes. One thing to do is if you make a mistake then check to see if anyone else has made a similar mistake. git grep repalce If enough people make that specific mistake then consider adding it to the list of commonly mispelled words: scripts/spelling.txt I looked through the logs and it looks like someone mispells it once a year so it's probably not common enough to worry about. regards, dan carpenter
[PATCH v4 2/2] usb: dwc3: Add driver for Xilinx platforms
Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 339 ++ 4 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 2133acf..66b1454 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -149,4 +149,13 @@ config USB_DWC3_IMX8MP functionality. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 2259f88..2d499de 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM)+= dwc3-qcom.o obj-$(CONFIG_USB_DWC3_IMX8MP) += dwc3-imx8mp.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index e62ecd2..71fd620 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index 000..a59e149 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST_EN0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define XLNX_USB_FPD_PIPE_CLK 0x7c +#define PIPE_CLK_DESELECT 1 +#define PIPE_CLK_SELECT0 +#define XLNX_USB_FPD_POWER_PRSNT 0x80 +#define FPD_POWER_PRSNT_OPTION BIT(0) + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device *dev; + void __iomem*regs; + int (*pltfm_init)(struct dwc3_xlnx *data); +}; + +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) +{ + u32 reg; + + /* +* Enable or disable ULPI PHY reset from USB Controller. +* This does not actually reset the phy, but just controls +* whether USB controller can or cannot reset ULPI PHY. +*/ + reg = readl(priv_data->regs + XLNX_USB_PHY_RST_EN); + + if (mask) + reg &= ~XLNX_PHY_RST_MASK; + else + reg |= XLNX_PHY_RST_MASK; + + writel(reg, priv_data->regs + XLNX_USB_PHY_RST_EN); +} + +static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) +{ + struct device *dev = priv_data->dev; + int ret; + + dwc3_xlnx_mask_phy_rst(priv_data, false); + + /* Assert and De-assert reset */ + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_ID, +PM_RESET_ACTION_ASSERT); + if (ret < 0) { + dev_err_probe(dev, ret, "failed to assert Reset\n"); + retu
[PATCH v4 0/2] Add a separate DWC3 OF driver for Xilinx platforms
This patch series documents the Xilinx Versal DWC3 controller. This also adds a new Xilinx specific driver for adding new features in the future. Changes in v2: - Addressed review comments from v1 - merged normal and runtime suspend resume functions as they are same - Improved description of some register operations to avoid confusion - Updated commit log for patch 2/2 for better clarity. Changes in v3: - Removed snps,enable-hibernation property from the devicetree binding. Changes in v4: - Error checking added for devm_phy_get - Documented resets in dt-bindings Manish Narani (2): dt-bindings: usb: dwc3-xilinx: Add documentation for Versal DWC3 Controller usb: dwc3: Add driver for Xilinx platforms .../devicetree/bindings/usb/dwc3-xilinx.txt| 28 +- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c | 339 + 5 files changed, 375 insertions(+), 3 deletions(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c -- 2.1.1
Re: [PATCH v2 1/2] media: staging/intel-ipu3: Fix memory leak in imu_fmt
On 3/17/21 1:50 AM, Ricardo Ribalda wrote: > Hi Bingbu > > Thanks for your review > > On Tue, Mar 16, 2021 at 12:29 PM Bingbu Cao > wrote: >> >> Hi, Ricardo >> >> Thanks for your patch. >> It looks fine for me, do you mind squash 2 patchsets into 1 commit? > > Are you sure? There are two different issues that we are solving. Oh, I see. I thought you were fixing 1 issue here. Thanks! > > Best regards! > >> >> On 3/15/21 8:34 PM, Ricardo Ribalda wrote: >>> We are losing the reference to an allocated memory if try. Change the >>> order of the check to avoid that. >>> >>> Cc: sta...@vger.kernel.org >>> Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack >>> usage") >>> Signed-off-by: Ricardo Ribalda >>> --- >>> drivers/staging/media/ipu3/ipu3-v4l2.c | 11 +++ >>> 1 file changed, 7 insertions(+), 4 deletions(-) >>> >>> diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c >>> b/drivers/staging/media/ipu3/ipu3-v4l2.c >>> index 60aa02eb7d2a..35a74d99322f 100644 >>> --- a/drivers/staging/media/ipu3/ipu3-v4l2.c >>> +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c >>> @@ -693,6 +693,13 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned >>> int pipe, int node, >>> if (inode == IMGU_NODE_STAT_3A || inode == IMGU_NODE_PARAMS) >>> continue; >>> >>> + /* CSS expects some format on OUT queue */ >>> + if (i != IPU3_CSS_QUEUE_OUT && >>> + !imgu_pipe->nodes[inode].enabled) { >>> + fmts[i] = NULL; >>> + continue; >>> + } >>> + >>> if (try) { >>> fmts[i] = >>> kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, >>> sizeof(struct >>> v4l2_pix_format_mplane), >>> @@ -705,10 +712,6 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned >>> int pipe, int node, >>> fmts[i] = >>> &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; >>> } >>> >>> - /* CSS expects some format on OUT queue */ >>> - if (i != IPU3_CSS_QUEUE_OUT && >>> - !imgu_pipe->nodes[inode].enabled) >>> - fmts[i] = NULL; >>> } >>> >>> if (!try) { >>> >> >> -- >> Best regards, >> Bingbu Cao > > > -- Best regards, Bingbu Cao
Re: [PATCH 2/2] erofs: use sync decompression for atomic contexts only
On 2021/3/17 11:54, Huang Jianan via Linux-erofs wrote: Sync decompression was introduced to get rid of additional kworker scheduling overhead. But there is no such overhead in non-atomic contexts. Therefore, it should be better to turn off sync decompression to avoid the current thread waiting in z_erofs_runqueue. Signed-off-by: Huang Jianan Signed-off-by: Guo Weichao Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Thanks,
Re: [question] Panic in dax_writeback_one
Thanks for the advices. I will check out that. 在 2021/3/17 12:55, Dan Williams 写道: > On Tue, Mar 16, 2021 at 8:00 PM chenjun (AM) wrote: >> >> 在 2021/3/12 1:25, Dan Williams 写道: >>> On Thu, Mar 11, 2021 at 4:20 AM Matthew Wilcox wrote: On Thu, Mar 11, 2021 at 07:48:25AM +, chenjun (AM) wrote: > static int dax_writeback_one(struct xa_state *xas, struct dax_device > *dax_dev, struct address_space *mapping, void *entry) > dax_flush(dax_dev, page_address(pfn_to_page(pfn)), count * PAGE_SIZE); > The pfn is returned by the driver. In my case, the pfn does not have > struct page. so pfn_to_page(pfn) return a wrong address. I wasn't involved, but I think the right solution here is simply to replace page_address(pfn_to_page(pfn)) with pfn_to_virt(pfn). I don't know why Dan decided to do this in the more complicated way. >>> >>> pfn_to_virt() only works for the direct-map. If pages are not mapped I >>> don't see how pfn_to_virt() is expected to work. >>> >>> The real question Chenjun is why are you writing a new simulator of >>> memory as a block-device vs reusing the pmem driver or brd? >>> >> >> Hi Dan >> >> In my case, I do not want to take memory to create the struct page of >> the memory my driver used. > > There are efforts happening to drastically reduce that overhead. You > might want to check out Joao's work [1]. I think that direction holds > more promise than trying to extend FS_DAX_LIMITED. > > [1]: http://lore.kernel.org/r/20201208172901.17384-1-joao.m.mart...@oracle.com > >> And, I think this is also a problem for DCSSBLK. > > If I understand correctly DAX replaced XIP for S390. There have not > been reports about this problem, and I can only guess because XIP > (eXecute-In-Place) is a read-only use case where dax_writeback_one() > is never triggered, or S390 just isn't using DCSSBLK anymore. The last > time I touched FS_DAX_LIMITED the DCSSBLK maintainers offered to just > delete this driver to get it out of the way. > >> >> So I want to go back the older way if CONFIG_FS_DAX_LIMITED >> >> diff --git a/fs/dax.c b/fs/dax.c >> index b3d27fd..6395e84 100644 >> --- a/fs/dax.c >> +++ b/fs/dax.c >> @@ -867,6 +867,9 @@ static int dax_writeback_one(struct xa_state *xas, >> struct dax_device *dax_dev, >>{ >> unsigned long pfn, index, count; >> long ret = 0; >> + void *kaddr; >> + pfn_t new_pfn_t; >> + pgoff_t pgoff; >> >> /* >> * A page got tagged dirty in DAX mapping? Something is seriously >> @@ -926,7 +929,25 @@ static int dax_writeback_one(struct xa_state *xas, >> struct dax_device *dax_dev, >> index = xas->xa_index & ~(count - 1); >> >> dax_entry_mkclean(mapping, index, pfn); >> - dax_flush(dax_dev, page_address(pfn_to_page(pfn)), count * >> PAGE_SIZE); >> + >> + if (!IS_ENABLED(CONFIG_FS_DAX_LIMITED) || pfn_valid(pfn)) >> + kaddr = page_address(pfn_to_page(pfn)); >> + else { >> + ret = bdev_dax_pgoff(mapping->host->i_sb->s_bdev, pfn << >> PFN_SECTION_SHIFT, count << PAGE_SHIFT, &pgoff); > > This is broken: > > mapping->host->i_sb->s_bdev > > ...there is no guarantee that the superblock associated with the > mapping is hosted on the same block device associated with the passed > in dax_device. See dax_rtdev in xfs_open_devices(). > -- Regards Chen Jun
[PATCH] sched: replace if (cond) BUG() with BUG_ON()
Fix the following coccicheck warnings: ./arch/powerpc/platforms/cell/spufs/sched.c:908:2-5: WARNING: Use BUG_ON instead of if condition followed by BUG. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong --- arch/powerpc/platforms/cell/spufs/sched.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 3692064..139a6ec 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -904,8 +904,7 @@ static noinline void spusched_tick(struct spu_context *ctx) struct spu_context *new = NULL; struct spu *spu = NULL; - if (spu_acquire(ctx)) - BUG(); /* a kernel thread never has signals pending */ + BUG_ON(spu_acquire(ctx)); /* a kernel thread never has signals pending */ if (ctx->state != SPU_STATE_RUNNABLE) goto out; -- 1.8.3.1
Re: [PATCH 1/2] erofs: use workqueue decompression for atomic contexts only
On 2021/3/17 11:54, Huang Jianan via Linux-erofs wrote: z_erofs_decompressqueue_endio may not be executed in the atomic context, for example, when dm-verity is turned on. In this scenario, data can be decompressed directly to get rid of additional kworker scheduling overhead. Signed-off-by: Huang Jianan Signed-off-by: Guo Weichao Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Thanks,
Re: [PATCH v15 0/4] Adding the Sparx5 Serdes driver
On 18-02-21, 17:14, Steen Hegelund wrote: > Adding the Sparx5 Serdes driver > > This series of patches provides the serdes driver for the Microchip Sparx5 > ethernet switch. > > The serdes driver supports the 10G and 25G serdes instances available in the > Sparx5. > > The Sparx5 serdes support several interface modes with several speeds and also > allows the client to change the mode and the speed according to changing in > the > environment such as changing cables from DAC to fiber. Applied patch 1 thru 3... thanks -- ~Vinod
[rcu:rcu/next] BUILD REGRESSION 9035ae87fcb36d2a7c8872e1cc0a46c0c5b619a8
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next branch HEAD: 9035ae87fcb36d2a7c8872e1cc0a46c0c5b619a8 torture: Fix grace-period rate output Error/Warning reports: https://lore.kernel.org/lkml/202103170728.9kxvazbv-...@intel.com Error/Warning in current branch: ERROR: modpost: "rcu_read_lock_longwait" [kernel/rcu/rcutorture.ko] undefined! ERROR: modpost: "rcu_read_lock_longwait_held" [kernel/rcu/rcutorture.ko] undefined! ERROR: modpost: "rcu_read_unlock_longwait" [kernel/rcu/rcutorture.ko] undefined! Error/Warning ids grouped by kconfigs: gcc_recent_errors |-- i386-randconfig-m021-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- i386-randconfig-s001-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- s390-defconfig | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- x86_64-randconfig-a011-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- x86_64-randconfig-a013-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- x86_64-randconfig-a015-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- x86_64-randconfig-a016-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- x86_64-randconfig-m001-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- x86_64-randconfig-r015-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined |-- x86_64-randconfig-r016-20210316 | |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined | |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined | `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined `-- x86_64-rhel-8.3 |-- ERROR:rcu_read_lock_longwait-kernel-rcu-rcutorture.ko-undefined |-- ERROR:rcu_read_lock_longwait_held-kernel-rcu-rcutorture.ko-undefined `-- ERROR:rcu_read_unlock_longwait-kernel-rcu-rcutorture.ko-undefined elapsed time: 722m configs tested: 119 configs skipped: 2 gcc tested configs: arm defconfig arm64allyesconfig arm64 defconfig arm allyesconfig arm allmodconfig riscvallmodconfig i386 allyesconfig riscvallyesconfig arm hackkit_defconfig arm gemini_defconfig sh j2_defconfig arm vf610m4_defconfig powerpc pmac32_defconfig sh se7705_defconfig nios2 10m50_defconfig sh apsh4a3a_defconfig powerpcklondike_defconfig powerpc ppc64_defconfig armcerfcube_defconfig nios2 3c120_defconfig pariscgeneric-32bit_defconfig powerpc ppc6xx_defconfig microblaze mmu_defconfig powerpc ps3_defconfig sh se7206_defconfig arm netwinder_defconfig arm spitz_defconfig mipsnlm_xlp_defconfig armspear6xx_defconfig powerpc taishan_defconfig arm lpc32xx_defconfig arm
Re: [PATCH 13/13] MAINTAINERS: Add entry for the bitmap API
On Wed, Mar 17, 2021 at 5:57 AM Joe Perches wrote: > > On Tue, 2021-03-16 at 21:47 -0700, Yury Norov wrote: > > [CC Andy Whitcroft, Joe Perches, Dwaipayan Ray, Lukas Bulwahn] > > > > On Tue, Mar 16, 2021 at 01:45:51PM +0200, Andy Shevchenko wrote: > > > On Mon, Mar 15, 2021 at 06:54:24PM -0700, Yury Norov wrote: > > > > Add myself as maintainer for bitmap API and Andy and Rasmus as > > > > reviewers. > > > > > > > > I'm an author of current implementation of lib/find_bit and an active > > > > contributor to lib/bitmap. It was spotted that there's no maintainer for > > > > bitmap API. I'm willing to maintain it. > > > > > > > > Signed-off-by: Yury Norov > > > > Acked-by: Andy Shevchenko > > > > Acked-by: Rasmus Villemoes > > > > --- > > > > MAINTAINERS | 16 > > > > 1 file changed, 16 insertions(+) > > > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > index 3dd20015696e..44f94cdd5a20 100644 > > > > --- a/MAINTAINERS > > > > +++ b/MAINTAINERS > > > > @@ -3151,6 +3151,22 @@ F: Documentation/filesystems/bfs.rst > > > > F: fs/bfs/ > > > > F: include/uapi/linux/bfs_fs.h > > > > > > > > > > > > +BITMAP API > > > > +M: Yury Norov > > > > +R: Andy Shevchenko > > > > +R: Rasmus Villemoes > > > > +S: Maintained > > > > +F: include/asm-generic/bitops/find.h > > > > +F: include/linux/bitmap.h > > > > +F: lib/bitmap.c > > > > +F: lib/find_bit.c > > > > > > > +F: lib/find_find_bit_benchmark.c > > > > > > Does this file exist? > > > I guess checkpatch.pl nowadays has a MAINTAINER data base validation. > > > > No lib/find_find_bit_benchmark.c doesn't exist. It's a typo, it should > > be lib/find_bit_benchmark.c. Checkpatch doesn't warn: > > > > yury:linux$ scripts/checkpatch.pl > > 0013-MAINTAINERS-Add-entry-for-the-bitmap-API.patch > > total: 0 errors, 0 warnings, 22 lines checked > > checkpatch does not validate filenames for each patch. > > checkpatch does have a --self-test=patterns capability that does > validate file accessibility. Joe meant: get_maintainers does have a --self-test=patterns capability that does validate file accessibility. You can run that before patch submission; otherwise, I run that script on linux-next once a week and send out correction patches as far as my "spare" time allows to do so. Lukas
Re: [PATCH 08/10] dt-bindings: phy: Add compatible for Mediatek MT8195
On 16-03-21, 19:14, Seiya Wang wrote: > This commit adds dt-binding documentation of UFS M-Phy for Mediatek MT8195 SoC > Platform. Applied, thanks -- ~Vinod
Re: [PATCH] btrfs: Use immediate assignment when referencing cc-option
On 17.03.21 г. 0:46 ч., Victor Erminpour wrote: > Calling cc-option will use KBUILD_CFLAGS, which when lazy setting > subdir-ccflags-y produces the following build error: > > scripts/Makefile.lib:10: *** Recursive variable `KBUILD_CFLAGS' \ > references itself (eventually). Stop. > > Use := assignment to subdir-ccflags-y when referencing cc-option. > This causes make to also evaluate += immediately, cc-option > calls are done right away and we don't end up with KBUILD_CFLAGS > referencing itself. > > Signed-off-by: Victor Erminpour > --- > fs/btrfs/Makefile | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile > index b634c42115ea..3dba1336fa95 100644 > --- a/fs/btrfs/Makefile > +++ b/fs/btrfs/Makefile > @@ -7,10 +7,10 @@ subdir-ccflags-y += -Wmissing-format-attribute > subdir-ccflags-y += -Wmissing-prototypes > subdir-ccflags-y += -Wold-style-definition > subdir-ccflags-y += -Wmissing-include-dirs > -subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable) > -subdir-ccflags-y += $(call cc-option, -Wunused-const-variable) > -subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned) > -subdir-ccflags-y += $(call cc-option, -Wstringop-truncation) > +subdir-ccflags-y := $(call cc-option, -Wunused-but-set-variable) > +subdir-ccflags-y := $(call cc-option, -Wunused-const-variable) > +subdir-ccflags-y := $(call cc-option, -Wpacked-not-aligned) > +subdir-ccflags-y := $(call cc-option, -Wstringop-truncation) > # The following turn off the warnings enabled by -Wextra > subdir-ccflags-y += -Wno-missing-field-initializers > subdir-ccflags-y += -Wno-sign-compare > Why does this patch change only some assignments and others are left as they were?
Re: [PATCH 07/10] dt-bindings: phy: Add compatible for Mediatek MT8195
On 16-03-21, 19:14, Seiya Wang wrote: > This commit adds dt-binding documentation of T-Phy for Mediatek MT8195 SoC > Platform. Applied, thanks -- ~Vinod
[PATCH V3 1/2] dt-bindings: iio: st,st-sensors add IIS2MDC.
Add support for ST magnetometer IIS2MDC, an I2C/SPI interface 3-axis magnetometer sensor. The patch was tested on the instrument with IIS2MDC via I2C interface. Acked-by: Rob Herring Signed-off-by: LI Qingwu --- Documentation/devicetree/bindings/iio/st,st-sensors.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml index db291a9390b7..7e98f47987dc 100644 --- a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml +++ b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml @@ -66,6 +66,7 @@ properties: - st,lis3mdl-magn - st,lis2mdl - st,lsm9ds1-magn + - st,iis2mdc # Pressure sensors - st,lps001wp-press - st,lps25h-press -- 2.17.1
[PATCH V3 2/2] iio:magnetometer: Add Support for ST IIS2MDC
Add support for ST magnetometer IIS2MDC, an I2C/SPI interface 3-axis magnetometer. The patch was tested on the instrument with IIS2MDC via I2C interface. Signed-off-by: LI Qingwu --- drivers/iio/magnetometer/st_magn.h | 1 + drivers/iio/magnetometer/st_magn_core.c | 1 + drivers/iio/magnetometer/st_magn_i2c.c | 5 + drivers/iio/magnetometer/st_magn_spi.c | 5 + 4 files changed, 12 insertions(+) diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h index 204b285725c8..7ba6a6ba5c58 100644 --- a/drivers/iio/magnetometer/st_magn.h +++ b/drivers/iio/magnetometer/st_magn.h @@ -21,6 +21,7 @@ #define LSM303AGR_MAGN_DEV_NAME"lsm303agr_magn" #define LIS2MDL_MAGN_DEV_NAME "lis2mdl" #define LSM9DS1_MAGN_DEV_NAME "lsm9ds1_magn" +#define IIS2MDC_MAGN_DEV_NAME "iis2mdc" const struct st_sensor_settings *st_magn_get_settings(const char *name); int st_magn_common_probe(struct iio_dev *indio_dev); diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 79de721e6015..71faebd07feb 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -337,6 +337,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { .sensors_supported = { [0] = LSM303AGR_MAGN_DEV_NAME, [1] = LIS2MDL_MAGN_DEV_NAME, + [2] = IIS2MDC_MAGN_DEV_NAME, }, .ch = (struct iio_chan_spec *)st_magn_3_16bit_channels, .odr = { diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index c6bb4ce77594..36f4e7b53b24 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -46,6 +46,10 @@ static const struct of_device_id st_magn_of_match[] = { .compatible = "st,lsm9ds1-magn", .data = LSM9DS1_MAGN_DEV_NAME, }, + { + .compatible = "st,iis2mdc", + .data = IIS2MDC_MAGN_DEV_NAME, + }, {}, }; MODULE_DEVICE_TABLE(of, st_magn_of_match); @@ -101,6 +105,7 @@ static const struct i2c_device_id st_magn_id_table[] = { { LSM303AGR_MAGN_DEV_NAME }, { LIS2MDL_MAGN_DEV_NAME }, { LSM9DS1_MAGN_DEV_NAME }, + { IIS2MDC_MAGN_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(i2c, st_magn_id_table); diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index 3d08d74c367d..0e2323dfc687 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -41,6 +41,10 @@ static const struct of_device_id st_magn_of_match[] = { .compatible = "st,lsm9ds1-magn", .data = LSM9DS1_MAGN_DEV_NAME, }, + { + .compatible = "st,iis2mdc", + .data = IIS2MDC_MAGN_DEV_NAME, + }, {} }; MODULE_DEVICE_TABLE(of, st_magn_of_match); @@ -92,6 +96,7 @@ static const struct spi_device_id st_magn_id_table[] = { { LSM303AGR_MAGN_DEV_NAME }, { LIS2MDL_MAGN_DEV_NAME }, { LSM9DS1_MAGN_DEV_NAME }, + { IIS2MDC_MAGN_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(spi, st_magn_id_table); -- 2.17.1
[PATCH V3 0/2] Add support for ST magnetometer IIS2MDC
Changes in V3: Reword the commit message, add "Acked-by: Rob Herring" LI Qingwu (2): dt-bindings: iio: st,st-sensors add IIS2MDC. iio:magnetometer: Add Support for ST IIS2MDC Documentation/devicetree/bindings/iio/st,st-sensors.yaml | 1 + drivers/iio/magnetometer/st_magn.h | 1 + drivers/iio/magnetometer/st_magn_core.c | 1 + drivers/iio/magnetometer/st_magn_i2c.c | 5 + drivers/iio/magnetometer/st_magn_spi.c | 5 + 5 files changed, 13 insertions(+) -- 2.17.1
Re: [PATCH v3] phy: qcom-qmp: add hbr3_hbr2 voltage and premphasis swing table
On 16-03-21, 10:12, Kuogee Hsieh wrote: > Add hbr3_hbr2 voltage and premphasis swing table to support > HBR3 link rate. > > Changes in V2: > -- replaced upper case with lower case at hbr3_hbr2 table > > Changes in v3: > -- replace space with tab at hbr3_hbr2 table This should be after the --- line below > > Signed-off-by: Kuogee Hsieh No need of blank line here > > Reviewed-by: Stephen Boyd I took the liberty of fixing these two, applying the fixes tag and applied.. -- ~Vinod
Re: [net PATCH 4/9] octeontx2-af: Remove TOS field from MKEX TX
Hi Jakub, On Tue, Mar 16, 2021 at 10:53 PM Jakub Kicinski wrote: > > On Tue, 16 Mar 2021 14:57:08 +0530 Hariprasad Kelam wrote: > > From: Subbaraya Sundeep > > > > TOS overlaps with DMAC field in mcam search key and hence installing > > rules for TX side are failing. Hence remove TOS field from TX profile. > > Could you clarify what "installing rules is failing" means? > Return error or does not behave correctly? Returns error. The MKEX profile can be in a way where higher layer packet fields can overwrite lower layer packet fields in output MCAM Key. The commit 42006910 ("octeontx2-af: cleanup KPU config data") introduced TX TOS field and it overwrites DMAC. AF driver return error when TX rule is installed with DMAC as match criteria since DMAC gets overwritten and cannot be supported. Layers from lower to higher in our case: LA - Ethernet LB - VLAN LC - IP LD - TCP/UDP and so on. We make sure there are no overlaps between layers but TOS got added by mistake. We will elaborate the commit description and send the next version. Thanks, Sundeep
Re: [PATCH v10 1/2] scsi: ufs: Enable power management for wlun
On 16/03/21 10:35 pm, Asutosh Das (asd) wrote: > On 3/16/2021 12:48 AM, Adrian Hunter wrote: >> On 16/03/21 12:22 am, Asutosh Das (asd) wrote: >>> On 3/14/2021 1:11 AM, Adrian Hunter wrote: On 10/03/21 5:04 am, Asutosh Das (asd) wrote: > On 3/9/2021 7:56 AM, Asutosh Das (asd) wrote: >> On 3/8/2021 9:17 AM, Rafael J. Wysocki wrote: >>> On Mon, Mar 8, 2021 at 5:21 PM Rafael J. Wysocki >>> wrote: On Sat, Mar 6, 2021 at 5:17 PM Alan Stern wrote: > > On Fri, Mar 05, 2021 at 06:54:24PM -0800, Asutosh Das (asd) wrote: > >> Now during my testing I see a weird issue sometimes (1 in 7). >> Scenario - bootups >> >> Issue: >> The supplier 'ufs_device_wlun 0:0:0:49488' goes into runtime suspend >> even >> when one/more of its consumers are in RPM_ACTIVE state. >> >> *Log: >> [ 10.056379][ T206] sd 0:0:0:1: [sdb] Synchronizing SCSI cache >> [ 10.062497][ T113] sd 0:0:0:5: [sdf] Synchronizing SCSI cache >> [ 10.356600][ T32] sd 0:0:0:7: [sdh] Synchronizing SCSI cache >> [ 10.362944][ T174] sd 0:0:0:3: [sdd] Synchronizing SCSI cache >> [ 10.696627][ T83] sd 0:0:0:2: [sdc] Synchronizing SCSI cache >> [ 10.704562][ T170] sd 0:0:0:6: [sdg] Synchronizing SCSI cache >> [ 10.980602][T5] sd 0:0:0:0: [sda] Synchronizing SCSI cache >> >> /** Printing all the consumer nodes of supplier **/ >> [ 10.987327][T5] ufs_device_wlun 0:0:0:49488: usage-count @ >> suspend: 0 >> <-- this is the usage_count >> [ 10.994440][T5] ufs_rpmb_wlun 0:0:0:49476: PM state - 2 >> [ 11.000402][T5] scsi 0:0:0:49456: PM state - 2 >> [ 11.005453][T5] sd 0:0:0:0: PM state - 2 >> [ 11.009958][T5] sd 0:0:0:1: PM state - 2 >> [ 11.014469][T5] sd 0:0:0:2: PM state - 2 >> [ 11.019072][T5] sd 0:0:0:3: PM state - 2 >> [ 11.023595][T5] sd 0:0:0:4: PM state - 0 << RPM_ACTIVE >> [ 11.353298][T5] sd 0:0:0:5: PM state - 2 >> [ 11.357726][T5] sd 0:0:0:6: PM state - 2 >> [ 11.362155][T5] sd 0:0:0:7: PM state - 2 >> [ 11.366584][T5] ufshcd-qcom 1d84000.ufshc: >> __ufshcd_wl_suspend - 8709 >> [ 11.374366][T5] ufs_device_wlun 0:0:0:49488: >> __ufshcd_wl_suspend - >> (0) has rpm_active flags Do you mean that rpm_active of the link between the consumer and the supplier is greater than 0 at this point and the consumer is >>> >>> I mean is rpm_active of the link greater than 1 (because 1 means "no >>> active references to the supplier")? >> Hi Rafael: >> No - it is not greater than 1. >> >> I'm trying to understand what's going on in it; will update when I've >> something. >> >>> RPM_ACTIVE, but the supplier suspends successfully nevertheless? >> [ 11.383376][T5] ufs_device_wlun 0:0:0:49488: >> ufshcd_wl_runtime_suspend <-- Supplier suspends fine. >> [ 12.977318][ T174] sd 0:0:0:4: [sde] Synchronizing SCSI cache >> >> And the the suspend of sde is stuck now: >> schedule+0x9c/0xe0 >> schedule_timeout+0x40/0x128 >> io_schedule_timeout+0x44/0x68 >> wait_for_common_io+0x7c/0x100 >> wait_for_completion_io+0x14/0x20 >> blk_execute_rq+0x90/0xcc >> __scsi_execute+0x104/0x1c4 >> sd_sync_cache+0xf8/0x2a0 >> sd_suspend_common+0x74/0x11c >> sd_suspend_runtime+0x14/0x20 >> scsi_runtime_suspend+0x64/0x94 >> __rpm_callback+0x80/0x2a4 >> rpm_suspend+0x308/0x614 >> pm_runtime_work+0x98/0xa8 >> >> I added 'DL_FLAG_RPM_ACTIVE' while creating links. >> if (hba->sdev_ufs_device) { >> link = device_link_add(&sdev->sdev_gendev, >> >> &hba->sdev_ufs_device->sdev_gendev, >> >> DL_FLAG_PM_RUNTIME|DL_FLAG_RPM_ACTIVE); >> I didn't expect this to resolve the issue anyway and it didn't. >> >> Another interesting point here is when I resume any of the above >> suspended >> consumers, it all goes back to normal, which is kind of expected. I >> tried >> resuming the consumer and the supplier is resumed and the supplier is >> suspended when all the consumers are suspended. >> >> Any pointers on this issue please? >> >> @Bart/@Alan - Do you've any pointers please? > > It's very noticeable that although you seem to have isolated a bug in > the power management subsystem (supplier goes into runtime suspend > even when one
Re: [PATCH 0/3] AM64: Add SERDES DT bindings
On 10-03-21, 16:57, Kishon Vijay Abraham I wrote: > Patch series adds device tree bindings to support SERDES in AM64 > platform. > > This is split from [1] since this binding is also required for AM64 > USB DT patches to be merged. > > Vinod, > > Once the 1st patch of the series is reviewed by Rob, can you merge and > prepare a immutable tag to be used by Nishant Menon so that he can merge > USB3 DT patches. Applied and tag: git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git tags/ti-serdes-for-5.13 -- ~Vinod
[PATCH] attr: replace if (cond) BUG() with BUG_ON()
Fix the following coccicheck warnings: ./fs/attr.c:349:2-5: WARNING: Use BUG_ON instead of if condition followed by BUG. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong --- fs/attr.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 87ef39d..43f369e 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -344,9 +344,7 @@ int notify_change(struct user_namespace *mnt_userns, struct dentry *dentry, * no function will ever call notify_change with both ATTR_MODE and * ATTR_KILL_S*ID set. */ - if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) && - (ia_valid & ATTR_MODE)) - BUG(); + BUG_ON((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) && (ia_valid & ATTR_MODE)); if (ia_valid & ATTR_KILL_SUID) { if (mode & S_ISUID) { -- 1.8.3.1
[PATCH] mwifiex: Remove unneeded variable: "ret"
From: zuoqilin Remove unneeded variable: "ret" Signed-off-by: zuoqilin --- drivers/net/wireless/marvell/mwifiex/scan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index c2a685f..0b877f3 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -1211,7 +1211,6 @@ enum cipher_suite { int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, struct mwifiex_bssdescriptor *bss_entry) { - int ret = 0; u8 element_id; struct ieee_types_fh_param_set *fh_param_set; struct ieee_types_ds_param_set *ds_param_set; @@ -1464,7 +1463,7 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bytes_left -= total_ie_len; } /* while (bytes_left > 2) */ - return ret; + return 0; } /* -- 1.9.1
Re: [PATCH] MIPS: fix memory reservation for non-usermem setups
Hi Ilya, On Tue, Mar 16, 2021 at 10:10:09PM -0700, Ilya Lipnitskiy wrote: > Hi Thomas, > > On Fri, Mar 12, 2021 at 7:19 AM Thomas Bogendoerfer > wrote: > > > > On Sun, Mar 07, 2021 at 11:40:30AM -0800, Ilya Lipnitskiy wrote: > > > From: Tobias Wolf > > > > > > Commit 67a3ba25aa95 ("MIPS: Fix incorrect mem=X@Y handling") introduced a > > > new > > > issue for rt288x where "PHYS_OFFSET" is 0x0 but the calculated "ramstart" > > > is > > > not. As the prerequisite of custom memory map has been removed, this > > > results > > > in the full memory range of 0x0 - 0x800 to be marked as reserved for > > > this > > > platform. > > > > and where is the problem here ? > Turns out this was already attempted to be upstreamed - not clear why > it wasn't merged. Context: > https://lore.kernel.org/linux-mips/6504517.U6H5IhoIOn@loki/ > > I hope the thread above helps you understand the problem. The memory initialization was a bit different then. Do you still see the same problem? -- Sincerely yours, Mike.
[PATCH v13 13/14] mm/vmalloc: Hugepage vmalloc mappings
Support huge page vmalloc mappings. Config option HAVE_ARCH_HUGE_VMALLOC enables support on architectures that define HAVE_ARCH_HUGE_VMAP and supports PMD sized vmap mappings. vmalloc will attempt to allocate PMD-sized pages if allocating PMD size or larger, and fall back to small pages if that was unsuccessful. Architectures must ensure that any arch specific vmalloc allocations that require PAGE_SIZE mappings (e.g., module allocations vs strict module rwx) use the VM_NOHUGE flag to inhibit larger mappings. This can result in more internal fragmentation and memory overhead for a given allocation, an option nohugevmalloc is added to disable at boot. Signed-off-by: Nicholas Piggin --- arch/Kconfig| 11 ++ include/linux/vmalloc.h | 21 mm/page_alloc.c | 5 +- mm/vmalloc.c| 216 +++- 4 files changed, 206 insertions(+), 47 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index ecfd3520b676..b347102f2984 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -785,6 +785,17 @@ config HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD config HAVE_ARCH_HUGE_VMAP bool +# +# Archs that select this would be capable of PMD-sized vmaps (i.e., +# arch_vmap_pmd_supported() returns true), and they must make no assumptions +# that vmalloc memory is mapped with PAGE_SIZE ptes. The VM_NO_HUGE_VMAP flag +# can be used to prohibit arch-specific allocations from using hugepages to +# help with this (e.g., modules may require it). +# +config HAVE_ARCH_HUGE_VMALLOC + depends on HAVE_ARCH_HUGE_VMAP + bool + config ARCH_WANT_HUGE_PMD_SHARE bool diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 1f6844e2670a..8341964e6eb5 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -26,6 +26,7 @@ struct notifier_block;/* in notifier.h */ #define VM_KASAN 0x0080 /* has allocated kasan shadow memory */ #define VM_FLUSH_RESET_PERMS 0x0100 /* reset direct map and flush TLB on unmap, can't be freed in atomic context */ #define VM_MAP_PUT_PAGES 0x0200 /* put pages and free array in vfree */ +#define VM_NO_HUGE_VMAP0x0400 /* force PAGE_SIZE pte mapping */ /* * VM_KASAN is used slighly differently depending on CONFIG_KASAN_VMALLOC. @@ -54,6 +55,9 @@ struct vm_struct { unsigned long size; unsigned long flags; struct page **pages; +#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC + unsigned intpage_order; +#endif unsigned intnr_pages; phys_addr_t phys_addr; const void *caller; @@ -188,6 +192,22 @@ void free_vm_area(struct vm_struct *area); extern struct vm_struct *remove_vm_area(const void *addr); extern struct vm_struct *find_vm_area(const void *addr); +static inline bool is_vm_area_hugepages(const void *addr) +{ + /* +* This may not 100% tell if the area is mapped with > PAGE_SIZE +* page table entries, if for some reason the architecture indicates +* larger sizes are available but decides not to use them, nothing +* prevents that. This only indicates the size of the physical page +* allocated in the vmalloc layer. +*/ +#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC + return find_vm_area(addr)->page_order > 0; +#else + return false; +#endif +} + #ifdef CONFIG_MMU int vmap_range(unsigned long addr, unsigned long end, phys_addr_t phys_addr, pgprot_t prot, @@ -205,6 +225,7 @@ static inline void set_vm_flush_reset_perms(void *addr) if (vm) vm->flags |= VM_FLUSH_RESET_PERMS; } + #else static inline int map_kernel_range_noflush(unsigned long start, unsigned long size, diff --git a/mm/page_alloc.c b/mm/page_alloc.c index cfc72873961d..2e2042f39b8b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include @@ -8222,6 +8223,7 @@ void *__init alloc_large_system_hash(const char *tablename, void *table = NULL; gfp_t gfp_flags; bool virt; + bool huge; /* allow the kernel cmdline to have a say */ if (!numentries) { @@ -8289,6 +8291,7 @@ void *__init alloc_large_system_hash(const char *tablename, } else if (get_order(size) >= MAX_ORDER || hashdist) { table = __vmalloc(size, gfp_flags); virt = true; + huge = is_vm_area_hugepages(table); } else { /* * If bucketsize is not a power-of-two, we may free @@ -8305,7 +8308,7 @@ void *__init alloc_large_system_hash(const char *tablename, pr_info("%s hash table entries: %ld (order: %d, %lu bytes, %s)\n", tablename, 1UL << log2qty, ilog2(size) - PAGE_SHIF
[PATCH v13 14/14] powerpc/64s/radix: Enable huge vmalloc mappings
This reduces TLB misses by nearly 30x on a `git diff` workload on a 2-node POWER9 (59,800 -> 2,100) and reduces CPU cycles by 0.54%, due to vfs hashes being allocated with 2MB pages. Cc: linuxppc-...@lists.ozlabs.org Acked-by: Michael Ellerman Signed-off-by: Nicholas Piggin --- .../admin-guide/kernel-parameters.txt | 2 ++ arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/module.c | 22 +++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 04545725f187..1f481f904895 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3243,6 +3243,8 @@ nohugeiomap [KNL,X86,PPC,ARM64] Disable kernel huge I/O mappings. + nohugevmalloc [PPC] Disable kernel huge vmalloc mappings. + nosmt [KNL,S390] Disable symmetric multithreading (SMT). Equivalent to smt=1. diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 386ae12d8523..b7cade9566da 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -181,6 +181,7 @@ config PPC select GENERIC_GETTIMEOFDAY select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU + select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14 select HAVE_ARCH_KASAN_VMALLOC if PPC32 && PPC_PAGE_SHIFT <= 14 diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index a211b0253cdb..cdb2d88c54e7 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -87,13 +88,26 @@ int module_finalize(const Elf_Ehdr *hdr, return 0; } -#ifdef MODULES_VADDR void *module_alloc(unsigned long size) { + unsigned long start = VMALLOC_START; + unsigned long end = VMALLOC_END; + +#ifdef MODULES_VADDR BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR); + start = MODULES_VADDR; + end = MODULES_END; +#endif + + /* +* Don't do huge page allocations for modules yet until more testing +* is done. STRICT_MODULE_RWX may require extra work to support this +* too. +*/ - return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, GFP_KERNEL, - PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, + return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, + PAGE_KERNEL_EXEC, + VM_NO_HUGE_VMAP | VM_FLUSH_RESET_PERMS, + NUMA_NO_NODE, __builtin_return_address(0)); } -#endif -- 2.23.0
[PATCH v13 10/14] mm/vmalloc: provide fallback arch huge vmap support functions
If an architecture doesn't support a particular page table level as a huge vmap page size then allow it to skip defining the support query function. Suggested-by: Christoph Hellwig Signed-off-by: Nicholas Piggin --- arch/arm64/include/asm/vmalloc.h | 7 +++ arch/powerpc/include/asm/vmalloc.h | 7 +++ arch/x86/include/asm/vmalloc.h | 13 + include/linux/vmalloc.h| 24 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h index fc9a12d6cc1a..7a22aeea9bb5 100644 --- a/arch/arm64/include/asm/vmalloc.h +++ b/arch/arm64/include/asm/vmalloc.h @@ -4,11 +4,8 @@ #include #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -static inline bool arch_vmap_p4d_supported(pgprot_t prot) -{ - return false; -} +#define arch_vmap_pud_supported arch_vmap_pud_supported static inline bool arch_vmap_pud_supported(pgprot_t prot) { /* @@ -19,11 +16,13 @@ static inline bool arch_vmap_pud_supported(pgprot_t prot) !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); } +#define arch_vmap_pmd_supported arch_vmap_pmd_supported static inline bool arch_vmap_pmd_supported(pgprot_t prot) { /* See arch_vmap_pud_supported() */ return !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); } + #endif #endif /* _ASM_ARM64_VMALLOC_H */ diff --git a/arch/powerpc/include/asm/vmalloc.h b/arch/powerpc/include/asm/vmalloc.h index 3f0c153befb0..4c69ece52a31 100644 --- a/arch/powerpc/include/asm/vmalloc.h +++ b/arch/powerpc/include/asm/vmalloc.h @@ -5,21 +5,20 @@ #include #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -static inline bool arch_vmap_p4d_supported(pgprot_t prot) -{ - return false; -} +#define arch_vmap_pud_supported arch_vmap_pud_supported static inline bool arch_vmap_pud_supported(pgprot_t prot) { /* HPT does not cope with large pages in the vmalloc area */ return radix_enabled(); } +#define arch_vmap_pmd_supported arch_vmap_pmd_supported static inline bool arch_vmap_pmd_supported(pgprot_t prot) { return radix_enabled(); } + #endif #endif /* _ASM_POWERPC_VMALLOC_H */ diff --git a/arch/x86/include/asm/vmalloc.h b/arch/x86/include/asm/vmalloc.h index e714b00fc0ca..49ce331f3ac6 100644 --- a/arch/x86/include/asm/vmalloc.h +++ b/arch/x86/include/asm/vmalloc.h @@ -6,24 +6,21 @@ #include #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -static inline bool arch_vmap_p4d_supported(pgprot_t prot) -{ - return false; -} +#ifdef CONFIG_X86_64 +#define arch_vmap_pud_supported arch_vmap_pud_supported static inline bool arch_vmap_pud_supported(pgprot_t prot) { -#ifdef CONFIG_X86_64 return boot_cpu_has(X86_FEATURE_GBPAGES); -#else - return false; -#endif } +#endif +#define arch_vmap_pmd_supported arch_vmap_pmd_supported static inline bool arch_vmap_pmd_supported(pgprot_t prot) { return boot_cpu_has(X86_FEATURE_PSE); } + #endif #endif /* _ASM_X86_VMALLOC_H */ diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 4b897a4a408b..82b45e1f28ff 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -78,10 +78,26 @@ struct vmap_area { }; }; -#ifndef CONFIG_HAVE_ARCH_HUGE_VMAP -static inline bool arch_vmap_p4d_supported(pgprot_t prot) { return false; } -static inline bool arch_vmap_pud_supported(pgprot_t prot) { return false; } -static inline bool arch_vmap_pmd_supported(pgprot_t prot) { return false; } +/* archs that select HAVE_ARCH_HUGE_VMAP should override one or more of these */ +#ifndef arch_vmap_p4d_supported +static inline bool arch_vmap_p4d_supported(pgprot_t prot) +{ + return false; +} +#endif + +#ifndef arch_vmap_pud_supported +static inline bool arch_vmap_pud_supported(pgprot_t prot) +{ + return false; +} +#endif + +#ifndef arch_vmap_pmd_supported +static inline bool arch_vmap_pmd_supported(pgprot_t prot) +{ + return false; +} #endif /* -- 2.23.0
[PATCH v13 12/14] mm/vmalloc: add vmap_range_noflush variant
As a side-effect, the order of flush_cache_vmap() and arch_sync_kernel_mappings() calls are switched, but that now matches the other callers in this file. Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Piggin --- mm/vmalloc.c | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 53414959845d..9455dba58b0e 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -240,7 +240,7 @@ static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end, return 0; } -int vmap_range(unsigned long addr, unsigned long end, +static int vmap_range_noflush(unsigned long addr, unsigned long end, phys_addr_t phys_addr, pgprot_t prot, unsigned int max_page_shift) { @@ -263,14 +263,24 @@ int vmap_range(unsigned long addr, unsigned long end, break; } while (pgd++, phys_addr += (next - addr), addr = next, addr != end); - flush_cache_vmap(start, end); - if (mask & ARCH_PAGE_TABLE_SYNC_MASK) arch_sync_kernel_mappings(start, end); return err; } +int vmap_range(unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot, + unsigned int max_page_shift) +{ + int err; + + err = vmap_range_noflush(addr, end, phys_addr, prot, max_page_shift); + flush_cache_vmap(addr, end); + + return err; +} + static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, pgtbl_mod_mask *mask) { -- 2.23.0
[PATCH v13 11/14] mm: Move vmap_range from mm/ioremap.c to mm/vmalloc.c
This is a generic kernel virtual memory mapper, not specific to ioremap. Code is unchanged other than making vmap_range non-static. Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Piggin --- include/linux/vmalloc.h | 3 + mm/ioremap.c| 203 mm/vmalloc.c| 202 +++ 3 files changed, 205 insertions(+), 203 deletions(-) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 82b45e1f28ff..1f6844e2670a 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -189,6 +189,9 @@ extern struct vm_struct *remove_vm_area(const void *addr); extern struct vm_struct *find_vm_area(const void *addr); #ifdef CONFIG_MMU +int vmap_range(unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot, + unsigned int max_page_shift); extern int map_kernel_range_noflush(unsigned long start, unsigned long size, pgprot_t prot, struct page **pages); int map_kernel_range(unsigned long start, unsigned long size, pgprot_t prot, diff --git a/mm/ioremap.c b/mm/ioremap.c index 3264d0203785..d1dcc7e744ac 100644 --- a/mm/ioremap.c +++ b/mm/ioremap.c @@ -28,209 +28,6 @@ early_param("nohugeiomap", set_nohugeiomap); static const bool iomap_max_page_shift = PAGE_SHIFT; #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ -static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, - phys_addr_t phys_addr, pgprot_t prot, - pgtbl_mod_mask *mask) -{ - pte_t *pte; - u64 pfn; - - pfn = phys_addr >> PAGE_SHIFT; - pte = pte_alloc_kernel_track(pmd, addr, mask); - if (!pte) - return -ENOMEM; - do { - BUG_ON(!pte_none(*pte)); - set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot)); - pfn++; - } while (pte++, addr += PAGE_SIZE, addr != end); - *mask |= PGTBL_PTE_MODIFIED; - return 0; -} - -static int vmap_try_huge_pmd(pmd_t *pmd, unsigned long addr, unsigned long end, - phys_addr_t phys_addr, pgprot_t prot, - unsigned int max_page_shift) -{ - if (max_page_shift < PMD_SHIFT) - return 0; - - if (!arch_vmap_pmd_supported(prot)) - return 0; - - if ((end - addr) != PMD_SIZE) - return 0; - - if (!IS_ALIGNED(addr, PMD_SIZE)) - return 0; - - if (!IS_ALIGNED(phys_addr, PMD_SIZE)) - return 0; - - if (pmd_present(*pmd) && !pmd_free_pte_page(pmd, addr)) - return 0; - - return pmd_set_huge(pmd, phys_addr, prot); -} - -static int vmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, - phys_addr_t phys_addr, pgprot_t prot, - unsigned int max_page_shift, pgtbl_mod_mask *mask) -{ - pmd_t *pmd; - unsigned long next; - - pmd = pmd_alloc_track(&init_mm, pud, addr, mask); - if (!pmd) - return -ENOMEM; - do { - next = pmd_addr_end(addr, end); - - if (vmap_try_huge_pmd(pmd, addr, next, phys_addr, prot, - max_page_shift)) { - *mask |= PGTBL_PMD_MODIFIED; - continue; - } - - if (vmap_pte_range(pmd, addr, next, phys_addr, prot, mask)) - return -ENOMEM; - } while (pmd++, phys_addr += (next - addr), addr = next, addr != end); - return 0; -} - -static int vmap_try_huge_pud(pud_t *pud, unsigned long addr, unsigned long end, - phys_addr_t phys_addr, pgprot_t prot, - unsigned int max_page_shift) -{ - if (max_page_shift < PUD_SHIFT) - return 0; - - if (!arch_vmap_pud_supported(prot)) - return 0; - - if ((end - addr) != PUD_SIZE) - return 0; - - if (!IS_ALIGNED(addr, PUD_SIZE)) - return 0; - - if (!IS_ALIGNED(phys_addr, PUD_SIZE)) - return 0; - - if (pud_present(*pud) && !pud_free_pmd_page(pud, addr)) - return 0; - - return pud_set_huge(pud, phys_addr, prot); -} - -static int vmap_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end, - phys_addr_t phys_addr, pgprot_t prot, - unsigned int max_page_shift, pgtbl_mod_mask *mask) -{ - pud_t *pud; - unsigned long next; - - pud = pud_alloc_track(&init_mm, p4d, addr, mask); - if (!pud) - return -ENOMEM; - do { - next = pud_addr_end(addr, end); - - if (vmap_try_huge_pud(pud, addr, next, phys_addr, prot, - max_page_shift)) { - *mask |= PGTBL_PUD_MODIFIED; -
[PATCH v13 06/14] mm: HUGE_VMAP arch support cleanup
This changes the awkward approach where architectures provide init functions to determine which levels they can provide large mappings for, to one where the arch is queried for each call. This removes code and indirection, and allows constant-folding of dead code for unsupported levels. This also adds a prot argument to the arch query. This is unused currently but could help with some architectures (e.g., some powerpc processors can't map uncacheable memory with large pages). Cc: linuxppc-...@lists.ozlabs.org Cc: Catalin Marinas Cc: Will Deacon Cc: linux-arm-ker...@lists.infradead.org Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: x...@kernel.org Cc: "H. Peter Anvin" Reviewed-by: Ding Tianhong Acked-by: Catalin Marinas [arm64] Signed-off-by: Nicholas Piggin --- arch/arm64/include/asm/vmalloc.h | 8 ++ arch/arm64/mm/mmu.c | 10 +-- arch/powerpc/include/asm/vmalloc.h | 8 ++ arch/powerpc/mm/book3s64/radix_pgtable.c | 8 +- arch/x86/include/asm/vmalloc.h | 7 ++ arch/x86/mm/ioremap.c| 12 +-- include/linux/io.h | 9 --- include/linux/vmalloc.h | 6 ++ init/main.c | 1 - mm/debug_vm_pgtable.c| 4 +- mm/ioremap.c | 94 ++-- 11 files changed, 87 insertions(+), 80 deletions(-) diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h index 2ca708ab9b20..597b40405319 100644 --- a/arch/arm64/include/asm/vmalloc.h +++ b/arch/arm64/include/asm/vmalloc.h @@ -1,4 +1,12 @@ #ifndef _ASM_ARM64_VMALLOC_H #define _ASM_ARM64_VMALLOC_H +#include + +#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP +bool arch_vmap_p4d_supported(pgprot_t prot); +bool arch_vmap_pud_supported(pgprot_t prot); +bool arch_vmap_pmd_supported(pgprot_t prot); +#endif + #endif /* _ASM_ARM64_VMALLOC_H */ diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 7484ea4f6ba0..639b9de61b1d 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1316,12 +1316,12 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot) return dt_virt; } -int __init arch_ioremap_p4d_supported(void) +bool arch_vmap_p4d_supported(pgprot_t prot) { - return 0; + return false; } -int __init arch_ioremap_pud_supported(void) +bool arch_vmap_pud_supported(pgprot_t prot) { /* * Only 4k granule supports level 1 block mappings. @@ -1331,9 +1331,9 @@ int __init arch_ioremap_pud_supported(void) !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); } -int __init arch_ioremap_pmd_supported(void) +bool arch_vmap_pmd_supported(pgprot_t prot) { - /* See arch_ioremap_pud_supported() */ + /* See arch_vmap_pud_supported() */ return !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); } diff --git a/arch/powerpc/include/asm/vmalloc.h b/arch/powerpc/include/asm/vmalloc.h index b992dfaaa161..105abb73f075 100644 --- a/arch/powerpc/include/asm/vmalloc.h +++ b/arch/powerpc/include/asm/vmalloc.h @@ -1,4 +1,12 @@ #ifndef _ASM_POWERPC_VMALLOC_H #define _ASM_POWERPC_VMALLOC_H +#include + +#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP +bool arch_vmap_p4d_supported(pgprot_t prot); +bool arch_vmap_pud_supported(pgprot_t prot); +bool arch_vmap_pmd_supported(pgprot_t prot); +#endif + #endif /* _ASM_POWERPC_VMALLOC_H */ diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index 98f0b243c1ab..743807fc210f 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -1082,13 +1082,13 @@ void radix__ptep_modify_prot_commit(struct vm_area_struct *vma, set_pte_at(mm, addr, ptep, pte); } -int __init arch_ioremap_pud_supported(void) +bool arch_vmap_pud_supported(pgprot_t prot) { /* HPT does not cope with large pages in the vmalloc area */ return radix_enabled(); } -int __init arch_ioremap_pmd_supported(void) +bool arch_vmap_pmd_supported(pgprot_t prot) { return radix_enabled(); } @@ -1182,7 +1182,7 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) return 1; } -int __init arch_ioremap_p4d_supported(void) +bool arch_vmap_p4d_supported(pgprot_t prot) { - return 0; + return false; } diff --git a/arch/x86/include/asm/vmalloc.h b/arch/x86/include/asm/vmalloc.h index 29837740b520..094ea2b565f3 100644 --- a/arch/x86/include/asm/vmalloc.h +++ b/arch/x86/include/asm/vmalloc.h @@ -1,6 +1,13 @@ #ifndef _ASM_X86_VMALLOC_H #define _ASM_X86_VMALLOC_H +#include #include +#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP +bool arch_vmap_p4d_supported(pgprot_t prot); +bool arch_vmap_pud_supported(pgprot_t prot); +bool arch_vmap_pmd_supported(pgprot_t prot); +#endif + #endif /* _ASM_X86_VMALLOC_H */ diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 9e5ccc56f8e0..fbaf0c447986 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -481,2
[PATCH v13 07/14] powerpc: inline huge vmap supported functions
This allows unsupported levels to be constant folded away, and so p4d_free_pud_page can be removed because it's no longer linked to. Cc: linuxppc-...@lists.ozlabs.org Acked-by: Michael Ellerman Signed-off-by: Nicholas Piggin --- arch/powerpc/include/asm/vmalloc.h | 19 --- arch/powerpc/mm/book3s64/radix_pgtable.c | 21 - 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/include/asm/vmalloc.h b/arch/powerpc/include/asm/vmalloc.h index 105abb73f075..3f0c153befb0 100644 --- a/arch/powerpc/include/asm/vmalloc.h +++ b/arch/powerpc/include/asm/vmalloc.h @@ -1,12 +1,25 @@ #ifndef _ASM_POWERPC_VMALLOC_H #define _ASM_POWERPC_VMALLOC_H +#include #include #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -bool arch_vmap_p4d_supported(pgprot_t prot); -bool arch_vmap_pud_supported(pgprot_t prot); -bool arch_vmap_pmd_supported(pgprot_t prot); +static inline bool arch_vmap_p4d_supported(pgprot_t prot) +{ + return false; +} + +static inline bool arch_vmap_pud_supported(pgprot_t prot) +{ + /* HPT does not cope with large pages in the vmalloc area */ + return radix_enabled(); +} + +static inline bool arch_vmap_pmd_supported(pgprot_t prot) +{ + return radix_enabled(); +} #endif #endif /* _ASM_POWERPC_VMALLOC_H */ diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index 743807fc210f..8da62afccee5 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -1082,22 +1082,6 @@ void radix__ptep_modify_prot_commit(struct vm_area_struct *vma, set_pte_at(mm, addr, ptep, pte); } -bool arch_vmap_pud_supported(pgprot_t prot) -{ - /* HPT does not cope with large pages in the vmalloc area */ - return radix_enabled(); -} - -bool arch_vmap_pmd_supported(pgprot_t prot) -{ - return radix_enabled(); -} - -int p4d_free_pud_page(p4d_t *p4d, unsigned long addr) -{ - return 0; -} - int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) { pte_t *ptep = (pte_t *)pud; @@ -1181,8 +1165,3 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) return 1; } - -bool arch_vmap_p4d_supported(pgprot_t prot) -{ - return false; -} -- 2.23.0
[PATCH v13 09/14] x86: inline huge vmap supported functions
This allows unsupported levels to be constant folded away, and so p4d_free_pud_page can be removed because it's no longer linked to. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: x...@kernel.org Cc: "H. Peter Anvin" Signed-off-by: Nicholas Piggin --- arch/x86/include/asm/vmalloc.h | 22 +++--- arch/x86/mm/ioremap.c | 21 - arch/x86/mm/pgtable.c | 13 - 3 files changed, 19 insertions(+), 37 deletions(-) diff --git a/arch/x86/include/asm/vmalloc.h b/arch/x86/include/asm/vmalloc.h index 094ea2b565f3..e714b00fc0ca 100644 --- a/arch/x86/include/asm/vmalloc.h +++ b/arch/x86/include/asm/vmalloc.h @@ -1,13 +1,29 @@ #ifndef _ASM_X86_VMALLOC_H #define _ASM_X86_VMALLOC_H +#include #include #include #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -bool arch_vmap_p4d_supported(pgprot_t prot); -bool arch_vmap_pud_supported(pgprot_t prot); -bool arch_vmap_pmd_supported(pgprot_t prot); +static inline bool arch_vmap_p4d_supported(pgprot_t prot) +{ + return false; +} + +static inline bool arch_vmap_pud_supported(pgprot_t prot) +{ +#ifdef CONFIG_X86_64 + return boot_cpu_has(X86_FEATURE_GBPAGES); +#else + return false; +#endif +} + +static inline bool arch_vmap_pmd_supported(pgprot_t prot) +{ + return boot_cpu_has(X86_FEATURE_PSE); +} #endif #endif /* _ASM_X86_VMALLOC_H */ diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index fbaf0c447986..12c686c65ea9 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -481,27 +481,6 @@ void iounmap(volatile void __iomem *addr) } EXPORT_SYMBOL(iounmap); -#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -bool arch_vmap_p4d_supported(pgprot_t prot) -{ - return false; -} - -bool arch_vmap_pud_supported(pgprot_t prot) -{ -#ifdef CONFIG_X86_64 - return boot_cpu_has(X86_FEATURE_GBPAGES); -#else - return false; -#endif -} - -bool arch_vmap_pmd_supported(pgprot_t prot) -{ - return boot_cpu_has(X86_FEATURE_PSE); -} -#endif - /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem * access diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index f6a9e2e36642..d27cf69e811d 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -780,14 +780,6 @@ int pmd_clear_huge(pmd_t *pmd) return 0; } -/* - * Until we support 512GB pages, skip them in the vmap area. - */ -int p4d_free_pud_page(p4d_t *p4d, unsigned long addr) -{ - return 0; -} - #ifdef CONFIG_X86_64 /** * pud_free_pmd_page - Clear pud entry and free pmd page. @@ -861,11 +853,6 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) #else /* !CONFIG_X86_64 */ -int pud_free_pmd_page(pud_t *pud, unsigned long addr) -{ - return pud_none(*pud); -} - /* * Disable free page handling on x86-PAE. This assures that ioremap() * does not update sync'd pmd entries. See vmalloc_sync_one(). -- 2.23.0
[PATCH v13 04/14] mm/vmalloc: rename vmap_*_range vmap_pages_*_range
The vmalloc mapper operates on a struct page * array rather than a linear physical address, re-name it to make this distinction clear. Reviewed-by: Miaohe Lin Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Piggin --- mm/vmalloc.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 98e697ac764c..4693fab4f42a 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -189,7 +189,7 @@ void unmap_kernel_range_noflush(unsigned long start, unsigned long size) arch_sync_kernel_mappings(start, end); } -static int vmap_pte_range(pmd_t *pmd, unsigned long addr, +static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, pgprot_t prot, struct page **pages, int *nr, pgtbl_mod_mask *mask) { @@ -217,7 +217,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, return 0; } -static int vmap_pmd_range(pud_t *pud, unsigned long addr, +static int vmap_pages_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, pgprot_t prot, struct page **pages, int *nr, pgtbl_mod_mask *mask) { @@ -229,13 +229,13 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, return -ENOMEM; do { next = pmd_addr_end(addr, end); - if (vmap_pte_range(pmd, addr, next, prot, pages, nr, mask)) + if (vmap_pages_pte_range(pmd, addr, next, prot, pages, nr, mask)) return -ENOMEM; } while (pmd++, addr = next, addr != end); return 0; } -static int vmap_pud_range(p4d_t *p4d, unsigned long addr, +static int vmap_pages_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end, pgprot_t prot, struct page **pages, int *nr, pgtbl_mod_mask *mask) { @@ -247,13 +247,13 @@ static int vmap_pud_range(p4d_t *p4d, unsigned long addr, return -ENOMEM; do { next = pud_addr_end(addr, end); - if (vmap_pmd_range(pud, addr, next, prot, pages, nr, mask)) + if (vmap_pages_pmd_range(pud, addr, next, prot, pages, nr, mask)) return -ENOMEM; } while (pud++, addr = next, addr != end); return 0; } -static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, +static int vmap_pages_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end, pgprot_t prot, struct page **pages, int *nr, pgtbl_mod_mask *mask) { @@ -265,7 +265,7 @@ static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, return -ENOMEM; do { next = p4d_addr_end(addr, end); - if (vmap_pud_range(p4d, addr, next, prot, pages, nr, mask)) + if (vmap_pages_pud_range(p4d, addr, next, prot, pages, nr, mask)) return -ENOMEM; } while (p4d++, addr = next, addr != end); return 0; @@ -306,7 +306,7 @@ int map_kernel_range_noflush(unsigned long addr, unsigned long size, next = pgd_addr_end(addr, end); if (pgd_bad(*pgd)) mask |= PGTBL_PGD_MODIFIED; - err = vmap_p4d_range(pgd, addr, next, prot, pages, &nr, &mask); + err = vmap_pages_p4d_range(pgd, addr, next, prot, pages, &nr, &mask); if (err) return err; } while (pgd++, addr = next, addr != end); -- 2.23.0
[PATCH v13 08/14] arm64: inline huge vmap supported functions
This allows unsupported levels to be constant folded away, and so p4d_free_pud_page can be removed because it's no longer linked to. Cc: Catalin Marinas Cc: Will Deacon Cc: linux-arm-ker...@lists.infradead.org Acked-by: Catalin Marinas Signed-off-by: Nicholas Piggin --- arch/arm64/include/asm/vmalloc.h | 23 --- arch/arm64/mm/mmu.c | 26 -- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h index 597b40405319..fc9a12d6cc1a 100644 --- a/arch/arm64/include/asm/vmalloc.h +++ b/arch/arm64/include/asm/vmalloc.h @@ -4,9 +4,26 @@ #include #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -bool arch_vmap_p4d_supported(pgprot_t prot); -bool arch_vmap_pud_supported(pgprot_t prot); -bool arch_vmap_pmd_supported(pgprot_t prot); +static inline bool arch_vmap_p4d_supported(pgprot_t prot) +{ + return false; +} + +static inline bool arch_vmap_pud_supported(pgprot_t prot) +{ + /* +* Only 4k granule supports level 1 block mappings. +* SW table walks can't handle removal of intermediate entries. +*/ + return IS_ENABLED(CONFIG_ARM64_4K_PAGES) && + !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); +} + +static inline bool arch_vmap_pmd_supported(pgprot_t prot) +{ + /* See arch_vmap_pud_supported() */ + return !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); +} #endif #endif /* _ASM_ARM64_VMALLOC_H */ diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 639b9de61b1d..1fb0035b0777 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1316,27 +1316,6 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot) return dt_virt; } -bool arch_vmap_p4d_supported(pgprot_t prot) -{ - return false; -} - -bool arch_vmap_pud_supported(pgprot_t prot) -{ - /* -* Only 4k granule supports level 1 block mappings. -* SW table walks can't handle removal of intermediate entries. -*/ - return IS_ENABLED(CONFIG_ARM64_4K_PAGES) && - !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); -} - -bool arch_vmap_pmd_supported(pgprot_t prot) -{ - /* See arch_vmap_pud_supported() */ - return !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); -} - int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) { pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot)); @@ -1428,11 +1407,6 @@ int pud_free_pmd_page(pud_t *pudp, unsigned long addr) return 1; } -int p4d_free_pud_page(p4d_t *p4d, unsigned long addr) -{ - return 0; /* Don't attempt a block mapping */ -} - #ifdef CONFIG_MEMORY_HOTPLUG static void __remove_pgd_mapping(pgd_t *pgdir, unsigned long start, u64 size) { -- 2.23.0
[PATCH v13 05/14] mm/ioremap: rename ioremap_*_range to vmap_*_range
This will be used as a generic kernel virtual mapping function, so re-name it in preparation. Reviewed-by: Miaohe Lin Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Piggin --- mm/ioremap.c | 64 +++- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/mm/ioremap.c b/mm/ioremap.c index 5fa1ab41d152..3f4d36f9745a 100644 --- a/mm/ioremap.c +++ b/mm/ioremap.c @@ -61,9 +61,9 @@ static inline int ioremap_pud_enabled(void) { return 0; } static inline int ioremap_pmd_enabled(void) { return 0; } #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ -static int ioremap_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, phys_addr_t phys_addr, pgprot_t prot, - pgtbl_mod_mask *mask) +static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot, + pgtbl_mod_mask *mask) { pte_t *pte; u64 pfn; @@ -81,9 +81,8 @@ static int ioremap_pte_range(pmd_t *pmd, unsigned long addr, return 0; } -static int ioremap_try_huge_pmd(pmd_t *pmd, unsigned long addr, - unsigned long end, phys_addr_t phys_addr, - pgprot_t prot) +static int vmap_try_huge_pmd(pmd_t *pmd, unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot) { if (!ioremap_pmd_enabled()) return 0; @@ -103,9 +102,9 @@ static int ioremap_try_huge_pmd(pmd_t *pmd, unsigned long addr, return pmd_set_huge(pmd, phys_addr, prot); } -static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr, - unsigned long end, phys_addr_t phys_addr, pgprot_t prot, - pgtbl_mod_mask *mask) +static int vmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot, + pgtbl_mod_mask *mask) { pmd_t *pmd; unsigned long next; @@ -116,20 +115,19 @@ static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr, do { next = pmd_addr_end(addr, end); - if (ioremap_try_huge_pmd(pmd, addr, next, phys_addr, prot)) { + if (vmap_try_huge_pmd(pmd, addr, next, phys_addr, prot)) { *mask |= PGTBL_PMD_MODIFIED; continue; } - if (ioremap_pte_range(pmd, addr, next, phys_addr, prot, mask)) + if (vmap_pte_range(pmd, addr, next, phys_addr, prot, mask)) return -ENOMEM; } while (pmd++, phys_addr += (next - addr), addr = next, addr != end); return 0; } -static int ioremap_try_huge_pud(pud_t *pud, unsigned long addr, - unsigned long end, phys_addr_t phys_addr, - pgprot_t prot) +static int vmap_try_huge_pud(pud_t *pud, unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot) { if (!ioremap_pud_enabled()) return 0; @@ -149,9 +147,9 @@ static int ioremap_try_huge_pud(pud_t *pud, unsigned long addr, return pud_set_huge(pud, phys_addr, prot); } -static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr, - unsigned long end, phys_addr_t phys_addr, pgprot_t prot, - pgtbl_mod_mask *mask) +static int vmap_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot, + pgtbl_mod_mask *mask) { pud_t *pud; unsigned long next; @@ -162,20 +160,19 @@ static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr, do { next = pud_addr_end(addr, end); - if (ioremap_try_huge_pud(pud, addr, next, phys_addr, prot)) { + if (vmap_try_huge_pud(pud, addr, next, phys_addr, prot)) { *mask |= PGTBL_PUD_MODIFIED; continue; } - if (ioremap_pmd_range(pud, addr, next, phys_addr, prot, mask)) + if (vmap_pmd_range(pud, addr, next, phys_addr, prot, mask)) return -ENOMEM; } while (pud++, phys_addr += (next - addr), addr = next, addr != end); return 0; } -static int ioremap_try_huge_p4d(p4d_t *p4d, unsigned long addr, - unsigned long end, phys_addr_t phys_addr, - pgprot_t prot) +static int vmap_try_huge_p4d(p4d_t *p4d, unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot) { if (!ioremap_p4d_enabled()) return 0; @@ -195,9 +192,9 @@ static int ioremap_try_huge_p4d(p4d_t *p4d, unsigned long addr, return p4d_set_huge(p4d, phys_addr, prot); } -static inline int ioremap_p
[PATCH v13 03/14] mm: apply_to_pte_range warn and fail if a large pte is encountered
apply_to_pte_range might mistake a large pte for bad, or treat it as a page table, resulting in a crash or corruption. Add a test to warn and return error if large entries are found. Reviewed-by: Miaohe Lin Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Piggin --- mm/memory.c | 66 +++-- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 5efa07fb6cdc..ccaf74f070c0 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2446,13 +2446,21 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud, } do { next = pmd_addr_end(addr, end); - if (create || !pmd_none_or_clear_bad(pmd)) { - err = apply_to_pte_range(mm, pmd, addr, next, fn, data, -create, mask); - if (err) - break; + if (pmd_none(*pmd) && !create) + continue; + if (WARN_ON_ONCE(pmd_leaf(*pmd))) + return -EINVAL; + if (!pmd_none(*pmd) && WARN_ON_ONCE(pmd_bad(*pmd))) { + if (!create) + continue; + pmd_clear_bad(pmd); } + err = apply_to_pte_range(mm, pmd, addr, next, +fn, data, create, mask); + if (err) + break; } while (pmd++, addr = next, addr != end); + return err; } @@ -2474,13 +2482,21 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d, } do { next = pud_addr_end(addr, end); - if (create || !pud_none_or_clear_bad(pud)) { - err = apply_to_pmd_range(mm, pud, addr, next, fn, data, -create, mask); - if (err) - break; + if (pud_none(*pud) && !create) + continue; + if (WARN_ON_ONCE(pud_leaf(*pud))) + return -EINVAL; + if (!pud_none(*pud) && WARN_ON_ONCE(pud_bad(*pud))) { + if (!create) + continue; + pud_clear_bad(pud); } + err = apply_to_pmd_range(mm, pud, addr, next, +fn, data, create, mask); + if (err) + break; } while (pud++, addr = next, addr != end); + return err; } @@ -2502,13 +2518,21 @@ static int apply_to_p4d_range(struct mm_struct *mm, pgd_t *pgd, } do { next = p4d_addr_end(addr, end); - if (create || !p4d_none_or_clear_bad(p4d)) { - err = apply_to_pud_range(mm, p4d, addr, next, fn, data, -create, mask); - if (err) - break; + if (p4d_none(*p4d) && !create) + continue; + if (WARN_ON_ONCE(p4d_leaf(*p4d))) + return -EINVAL; + if (!p4d_none(*p4d) && WARN_ON_ONCE(p4d_bad(*p4d))) { + if (!create) + continue; + p4d_clear_bad(p4d); } + err = apply_to_pud_range(mm, p4d, addr, next, +fn, data, create, mask); + if (err) + break; } while (p4d++, addr = next, addr != end); + return err; } @@ -2528,9 +2552,17 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr, pgd = pgd_offset(mm, addr); do { next = pgd_addr_end(addr, end); - if (!create && pgd_none_or_clear_bad(pgd)) + if (pgd_none(*pgd) && !create) continue; - err = apply_to_p4d_range(mm, pgd, addr, next, fn, data, create, &mask); + if (WARN_ON_ONCE(pgd_leaf(*pgd))) + return -EINVAL; + if (!pgd_none(*pgd) && WARN_ON_ONCE(pgd_bad(*pgd))) { + if (!create) + continue; + pgd_clear_bad(pgd); + } + err = apply_to_p4d_range(mm, pgd, addr, next, +fn, data, create, &mask); if (err) break; } while (pgd++, addr = next, addr != end); -- 2.23.0
[PATCH v13 02/14] mm/vmalloc: fix HUGE_VMAP regression by enabling huge pages in vmalloc_to_page
vmalloc_to_page returns NULL for addresses mapped by larger pages[*]. Whether or not a vmap is huge depends on the architecture details, alignments, boot options, etc., which the caller can not be expected to know. Therefore HUGE_VMAP is a regression for vmalloc_to_page. This change teaches vmalloc_to_page about larger pages, and returns the struct page that corresponds to the offset within the large page. This makes the API agnostic to mapping implementation details. [*] As explained by commit 029c54b095995 ("mm/vmalloc.c: huge-vmap: fail gracefully on unexpected huge vmap mappings") Reviewed-by: Miaohe Lin Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Piggin --- mm/vmalloc.c | 41 ++--- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 4f5f8c907897..98e697ac764c 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -34,7 +34,7 @@ #include #include #include - +#include #include #include #include @@ -343,7 +343,9 @@ int is_vmalloc_or_module_addr(const void *x) } /* - * Walk a vmap address to the struct page it maps. + * Walk a vmap address to the struct page it maps. Huge vmap mappings will + * return the tail page that corresponds to the base page address, which + * matches small vmap mappings. */ struct page *vmalloc_to_page(const void *vmalloc_addr) { @@ -363,25 +365,33 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) if (pgd_none(*pgd)) return NULL; + if (WARN_ON_ONCE(pgd_leaf(*pgd))) + return NULL; /* XXX: no allowance for huge pgd */ + if (WARN_ON_ONCE(pgd_bad(*pgd))) + return NULL; + p4d = p4d_offset(pgd, addr); if (p4d_none(*p4d)) return NULL; - pud = pud_offset(p4d, addr); + if (p4d_leaf(*p4d)) + return p4d_page(*p4d) + ((addr & ~P4D_MASK) >> PAGE_SHIFT); + if (WARN_ON_ONCE(p4d_bad(*p4d))) + return NULL; - /* -* Don't dereference bad PUD or PMD (below) entries. This will also -* identify huge mappings, which we may encounter on architectures -* that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be -* identified as vmalloc addresses by is_vmalloc_addr(), but are -* not [unambiguously] associated with a struct page, so there is -* no correct value to return for them. -*/ - WARN_ON_ONCE(pud_bad(*pud)); - if (pud_none(*pud) || pud_bad(*pud)) + pud = pud_offset(p4d, addr); + if (pud_none(*pud)) + return NULL; + if (pud_leaf(*pud)) + return pud_page(*pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT); + if (WARN_ON_ONCE(pud_bad(*pud))) return NULL; + pmd = pmd_offset(pud, addr); - WARN_ON_ONCE(pmd_bad(*pmd)); - if (pmd_none(*pmd) || pmd_bad(*pmd)) + if (pmd_none(*pmd)) + return NULL; + if (pmd_leaf(*pmd)) + return pmd_page(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT); + if (WARN_ON_ONCE(pmd_bad(*pmd))) return NULL; ptep = pte_offset_map(pmd, addr); @@ -389,6 +399,7 @@ struct page *vmalloc_to_page(const void *vmalloc_addr) if (pte_present(pte)) page = pte_page(pte); pte_unmap(ptep); + return page; } EXPORT_SYMBOL(vmalloc_to_page); -- 2.23.0
[PATCH v13 01/14] ARM: mm: add missing pud_page define to 2-level page tables
ARM uses its own PMD folding scheme which is missing pud_page which should just pass through to pmd_page. Move this from the 3-level page table to common header. Cc: Russell King Cc: Ding Tianhong Cc: linux-arm-ker...@lists.infradead.org Signed-off-by: Nicholas Piggin --- arch/arm/include/asm/pgtable-3level.h | 2 -- arch/arm/include/asm/pgtable.h| 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 2b85d175e999..d4edab51a77c 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h @@ -186,8 +186,6 @@ static inline pte_t pte_mkspecial(pte_t pte) #define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY)) #define pmd_dirty(pmd) (pmd_isset((pmd), L_PMD_SECT_DIRTY)) -#define pud_page(pud) pmd_page(__pmd(pud_val(pud))) -#define pud_write(pud) pmd_write(__pmd(pud_val(pud))) #define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd)) #define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd)) diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index c02f24400369..d63a5bb6bd0c 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -166,6 +166,9 @@ extern struct page *empty_zero_page; extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +#define pud_page(pud) pmd_page(__pmd(pud_val(pud))) +#define pud_write(pud) pmd_write(__pmd(pud_val(pud))) + #define pmd_none(pmd) (!pmd_val(pmd)) static inline pte_t *pmd_page_vaddr(pmd_t pmd) -- 2.23.0
[PATCH v13 00/14] huge vmalloc mappings
Important compound page fix thanks to Ding Tianhong. Thanks, Nick Since v12: - Use compound pages so it works with remap_vmalloc_range [noticed by Ding] - Fix debug_vm_pgtable.c compile error. Since v11: - ARM compile fix (patch 1) - debug_vm_pgtable compile fix Since v10: - Fixed code style, most > 80 colums, tweak patch titles, etc [thanks Christoph] - Made huge vmalloc code and data structure compile away if unselected [Christoph] - Archs only have to provide arch_vmap_p?d_supported for levels they implement [Christoph] Since v9: - Fixed intermediate build breakage on x86-32 !PAE [thanks Ding] - Fixed small page fallback case vm_struct double-free [thanks Ding] Since v8: - Fixed nommu compile. - Added Kconfig option help text - Added VM_NOHUGE which should help archs implement it [suggested by Rick] Since v7: - Rebase, added some acks, compile fix - Removed "order=" from vmallocinfo, it's a bit confusing (nr_pages is in small page size for compatibility). - Added arch_vmap_pmd_supported() test before starting to allocate the large page, rather than only testing it when doing the map, to avoid unsupported configs trying to allocate huge pages for no reason. Since v6: - Fixed a false positive warning introduced in patch 2, found by kbuild test robot. Since v5: - Split arch changes out better and make the constant folding work - Avoid most of the 80 column wrap, fix a reference to lib/ioremap.c - Fix compile error on some archs *** BLURB HERE *** Nicholas Piggin (14): ARM: mm: add missing pud_page define to 2-level page tables mm/vmalloc: fix HUGE_VMAP regression by enabling huge pages in vmalloc_to_page mm: apply_to_pte_range warn and fail if a large pte is encountered mm/vmalloc: rename vmap_*_range vmap_pages_*_range mm/ioremap: rename ioremap_*_range to vmap_*_range mm: HUGE_VMAP arch support cleanup powerpc: inline huge vmap supported functions arm64: inline huge vmap supported functions x86: inline huge vmap supported functions mm/vmalloc: provide fallback arch huge vmap support functions mm: Move vmap_range from mm/ioremap.c to mm/vmalloc.c mm/vmalloc: add vmap_range_noflush variant mm/vmalloc: Hugepage vmalloc mappings powerpc/64s/radix: Enable huge vmalloc mappings .../admin-guide/kernel-parameters.txt | 2 + arch/Kconfig | 11 + arch/arm/include/asm/pgtable-3level.h | 2 - arch/arm/include/asm/pgtable.h| 3 + arch/arm64/include/asm/vmalloc.h | 24 + arch/arm64/mm/mmu.c | 26 - arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/vmalloc.h| 20 + arch/powerpc/kernel/module.c | 22 +- arch/powerpc/mm/book3s64/radix_pgtable.c | 21 - arch/x86/include/asm/vmalloc.h| 20 + arch/x86/mm/ioremap.c | 19 - arch/x86/mm/pgtable.c | 13 - include/linux/io.h| 9 - include/linux/vmalloc.h | 46 ++ init/main.c | 1 - mm/debug_vm_pgtable.c | 4 +- mm/ioremap.c | 225 +--- mm/memory.c | 66 ++- mm/page_alloc.c | 5 +- mm/vmalloc.c | 485 +++--- 21 files changed, 621 insertions(+), 404 deletions(-) -- 2.23.0
{standard input}:3096: Error: operands mismatch -- statement `andl %a1,%d1' ignored
Hi Brendan, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 1df27313f50a57497c1faeb6a6ae4ca939c85a7d commit: 981f94c3e92146705baf97fb417a5ed1ab1a79a5 bpf: Add bitwise atomic instructions date: 9 weeks ago config: m68k-randconfig-r025-20210317 (attached as .config) compiler: m68k-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=981f94c3e92146705baf97fb417a5ed1ab1a79a5 git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git git fetch --no-tags linus master git checkout 981f94c3e92146705baf97fb417a5ed1ab1a79a5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): kernel/bpf/core.c:1350:12: warning: no previous prototype for 'bpf_probe_read_kernel' [-Wmissing-prototypes] 1350 | u64 __weak bpf_probe_read_kernel(void *dst, u32 size, const void *unsafe_ptr) |^ {standard input}: Assembler messages: {standard input}:3050: Error: invalid instruction for this architecture; needs 68020 or higher (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060]) -- statement `casl %d0,%d1,(%a6)' ignored >> {standard input}:3096: Error: operands mismatch -- statement `andl %a1,%d1' >> ignored {standard input}:3096: Error: invalid instruction for this architecture; needs 68020 or higher (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060]) -- statement `casl %d0,%d1,(%a6)' ignored >> {standard input}:3149: Error: operands mismatch -- statement `orl %a1,%d1' >> ignored {standard input}:3149: Error: invalid instruction for this architecture; needs 68020 or higher (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060]) -- statement `casl %d0,%d1,(%a6)' ignored >> {standard input}:3195: Error: operands mismatch -- statement `eorl %a1,%d1' >> ignored {standard input}:3195: Error: invalid instruction for this architecture; needs 68020 or higher (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060]) -- statement `casl %d0,%d1,(%a6)' ignored {standard input}:3218: Error: invalid instruction for this architecture; needs 68020 or higher (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060]) -- statement `casl %d0,%d5,(%a0)' ignored {standard input}:3255: Error: invalid instruction for this architecture; needs 68020 or higher (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060]) -- statement `casl %d0,%d5,(%a6)' ignored --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH 0/6] usbip fixes to crashes found by syzbot
Shuah, this driver is getting more and more cryptic and buggy. Please explain the strategy for serialization before you write patches. > - Fix attach_store() to check usbip_event_happened() before > waking up threads. No, this helps nothing. > diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c > index c4b4256e5dad3..f0a770adebd97 100644 > --- a/drivers/usb/usbip/vhci_sysfs.c > +++ b/drivers/usb/usbip/vhci_sysfs.c > @@ -418,6 +418,15 @@ static ssize_t attach_store(struct device *dev, struct > device_attribute *attr, > spin_unlock_irqrestore(&vhci->lock, flags); > /* end the lock */ > > + if (usbip_event_happened(&vdev->ud)) { > + /* > + * something went wrong - event handler shutting > + * the connection and doing reset - bail out > + */ > + dev_err(dev, "Event happended - handler is active\n"); > + return -EAGAIN; > + } > + detach_store() can queue shutdown event as soon as reaching "/* end the lock */" line but attach_store() might be preempted immediately after verifying that usbip_event_happened() was false (i.e. at this location) in order to wait for shutdown event posted by detach_store() to be processed. > wake_up_process(vdev->ud.tcp_rx); > wake_up_process(vdev->ud.tcp_tx); >
RE: [PATCH] exfat: improve write performance when dirsync enabled
> Degradation of write speed caused by frequent disk access for cluster > bitmap update on every cluster allocation could be improved by selective > syncing bitmap buffer. Change to flush bitmap buffer only for the > directory related operations. > > Signed-off-by: Hyeongseok Kim Looks good. Thanks for your work. Acked-by: Sungjong Seo
[PATCH] mwifiex: Remove redundant assignment
From: zuoqilin There is no need to define the err variable, and then assign -EINVAL, we can directly return -EINVAL. Signed-off-by: zuoqilin --- drivers/net/wireless/marvell/mwifiex/ie.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/ie.c b/drivers/net/wireless/marvell/mwifiex/ie.c index 40e99ea..c88213c 100644 --- a/drivers/net/wireless/marvell/mwifiex/ie.c +++ b/drivers/net/wireless/marvell/mwifiex/ie.c @@ -333,7 +333,6 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; int left_len, parsed_len = 0; unsigned int token_len; - int err = 0; if (!info->tail || !info->tail_len) return 0; @@ -351,7 +350,6 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, hdr = (void *)(info->tail + parsed_len); token_len = hdr->len + sizeof(struct ieee_types_header); if (token_len > left_len) { - err = -EINVAL; goto out; } @@ -377,7 +375,6 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, fallthrough; default: if (ie_len + token_len > IEEE_MAX_IE_SIZE) { - err = -EINVAL; goto out; } memcpy(gen_ie->ie_buffer + ie_len, hdr, token_len); @@ -397,7 +394,6 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, if (vendorhdr) { token_len = vendorhdr->len + sizeof(struct ieee_types_header); if (ie_len + token_len > IEEE_MAX_IE_SIZE) { - err = -EINVAL; goto out; } memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len); @@ -415,7 +411,6 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL, NULL, NULL)) { - err = -EINVAL; goto out; } @@ -423,7 +418,7 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, out: kfree(gen_ie); - return err; + return -EINVAL; } /* This function parses different IEs-head & tail IEs, beacon IEs, -- 1.9.1
Re: [PATCH] iio:imu:mpu6050: Modify matricies to matrices
On Tue, 16 Mar 2021 22:04:33 -0700 Randy Dunlap wrote: > On 3/16/21 7:41 PM, Guoqing chi wrote: > > From: Guoqing Chi > > > > The complex number of "matrix" is "matrices". > > (I would say that the plural of matrix is matrices.) Yes??your suggest is better. I will resent patch V2 for this. Thanks. > > > > > Signed-off-by: Guoqing Chi > > Acked-by: Randy Dunlap > > Thanks. > > > --- > > include/linux/platform_data/invensense_mpu6050.h | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/include/linux/platform_data/invensense_mpu6050.h > > b/include/linux/platform_data/invensense_mpu6050.h index > > 93974f4cfba1..f05b37521f67 100644 --- > > a/include/linux/platform_data/invensense_mpu6050.h +++ > > b/include/linux/platform_data/invensense_mpu6050.h @@ -12,7 +12,7 @@ > > * mounting matrix retrieved from > > device-tree) * > > * Contains platform specific information on how to configure the > > MPU6050 to > > - * work on this platform. The orientation matricies are 3x3 > > rotation matricies > > + * work on this platform. The orientation matrices are 3x3 > > rotation matrices > > * that are applied to the data to rotate from the mounting > > orientation to the > > * platform orientation. The values must be one of 0, 1, or -1 > > and each row and > > * column should have exactly 1 non-zero value. > > > >
Re: [PATCH v2 4/5] mtd: spi-nor: Move Software Write Protection logic out of the core
On 3/15/21 8:23 AM, Vignesh Raghavendra wrote: > EXTERNAL EMAIL: Do not click links or open attachments unless you know the > content is safe > > On 3/9/21 12:58 PM, tudor.amba...@microchip.com wrote: >> On 3/8/21 7:28 PM, Vignesh Raghavendra wrote: >>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the >>> content is safe >>> >>> On 3/6/21 3:20 PM, Tudor Ambarus wrote: It makes the core file a bit smaller and provides better separation between the Software Write Protection features and the core logic. All the next generic software write protection features (e.g. Individual Block Protection) will reside in swp.c. Signed-off-by: Tudor Ambarus --- drivers/mtd/spi-nor/Makefile | 2 +- drivers/mtd/spi-nor/core.c | 407 +- drivers/mtd/spi-nor/core.h | 4 + drivers/mtd/spi-nor/swp.c| 419 +++ >>> >>> Hmmm, name swp.c does not seem intuitive to me. How about expanding it a >>> bit: >>> >>> soft-wr-protect.c or software-write-protect.c ? Having in mind that we have the SWP configs, I think I prefer swp.c. But let's see what majority thinks, we'll do as majority prefers. Michael, Pratyush? >>> >> cut > > I am not a fan of renaming Kconfig options as it breaks make > olddefconfig flow which many developers rely on. > I'm fine keeping them as they are for now. If someone else screams we will reconsider.
Re: [mm, net-next v2] mm: net: memcg accounting for TCP rx zerocopy
On Tue, Mar 16, 2021 at 3:27 AM Johannes Weiner wrote: > > Hello, > > On Mon, Mar 15, 2021 at 09:16:45PM -0700, Arjun Roy wrote: > > From: Arjun Roy > > > > TCP zerocopy receive is used by high performance network applications > > to further scale. For RX zerocopy, the memory containing the network > > data filled by the network driver is directly mapped into the address > > space of high performance applications. To keep the TLB cost low, > > these applications unmap the network memory in big batches. So, this > > memory can remain mapped for long time. This can cause a memory > > isolation issue as this memory becomes unaccounted after getting > > mapped into the application address space. This patch adds the memcg > > accounting for such memory. > > > > Accounting the network memory comes with its own unique challenges. > > The high performance NIC drivers use page pooling to reuse the pages > > to eliminate/reduce expensive setup steps like IOMMU. These drivers > > keep an extra reference on the pages and thus we can not depend on the > > page reference for the uncharging. The page in the pool may keep a > > memcg pinned for arbitrary long time or may get used by other memcg. > > The page pool knows when a page is unmapped again and becomes > available for recycling, right? Essentially the 'free' phase of that > private allocator. That's where the uncharge should be done. > In general, no it does not. The page pool, how it operates and whether it exists in the first place, is an optimization that a given NIC driver can choose to make - and so there's no generic plumbing that ties page unmap events to something that a page pool could subscribe to that I am aware of. All it can do is check, at a given point, whether it can reuse a page or not, typically by checking the current page refcount. A couple of examples for drivers with such a mechanism - mlx5: (https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c#L248) Or intel fm10k: (https://github.com/torvalds/linux/blob/master/drivers/net/ethernet/intel/fm10k/fm10k_main.c#L207) Note that typically map count is not checked (maybe because page-flipping receive zerocopy did not exist as a consideration when the driver was written). So given that the page pool is essentially checking on demand for whether a page is usable or not - since there is no specific plumbing invoked when a page is usable again (i.e. unmapped, in this case) - we opted to hook into when the mapcount is decremented inside unmap() path. > For one, it's more aligned with the usual memcg charge lifetime rules. > > But also it doesn't add what is essentially a private driver callback > to the generic file unmapping path. > I understand the concern, and share it - the specific thing we'd like to avoid is to have driver specific code in the unmap path, and not in the least because any given driver could do its own thing. Rather, we consider this mechanism that we added as generic to zerocopy network data reception - that it does the right thing, no matter what the driver is doing. This would be transparent to the driver, in other words - all the driver has to do is to continue doing what it was before, using page->refcnt == 1 to decide whether it can use a page or if it is not already in use. Consider this instead as a broadly applicable networking feature adding a callback to the unmap path, instead of a particular driver. And while it is just TCP at present, it fundamentally isn't limited to TCP. I do have a request for clarification, if you could specify the usual memcg charge lifetime rules that you are referring to here? Just to make sure we're on the same page. > Finally, this will eliminate the need for making up a new charge type > (MEMCG_DATA_SOCK) and allow using the standard kmem charging API. > > > This patch decouples the uncharging of the page from the refcnt and > > associates it with the map count i.e. the page gets uncharged when the > > last address space unmaps it. Now the question is, what if the driver > > drops its reference while the page is still mapped? That is fine as > > the address space also holds a reference to the page i.e. the > > reference count can not drop to zero before the map count. > > > > Signed-off-by: Arjun Roy > > Co-developed-by: Shakeel Butt > > Signed-off-by: Shakeel Butt > > Signed-off-by: Eric Dumazet > > Signed-off-by: Soheil Hassas Yeganeh > > --- > > > > Changelog since v1: > > - Pages accounted for in this manner are now tracked via MEMCG_SOCK. > > - v1 allowed for a brief period of double-charging, now we have a > > brief period of under-charging to avoid undue memory pressure. > > I'm afraid we'll have to go back to v1. > > Let's address the issues raised with it: > > 1. The NR_FILE_MAPPED accounting. It is longstanding Linux behavior >that driver pages mapped into userspace are accounted as file >pages, because userspace is actually doing mmap() against a driver >fil
Re: RFC: MEDIA: Driver for ON Semi AR0521 camera sensor
Laurent Pinchart writes: >> Is there a reliable way to include national unicode characters in the >> kernel sources? > > It depends where. In comments it shouldn't be a problem. In C code, I > don't think the compiler will be too happy. I meant in comments, sure. And in stuff like MODULE_AUTHOR. I know gcc will handle it correctly, but the problem is getting the unicode characters right through mail. > Signed-off-by means that you have the right to submit the code for > upstreaming, so it should be included in patches under review too. > Otherwise it's a waste of time for reviewers to review something that > may never be resubmitted with an SoB line. I know. I obviously have rights to upstream this code. The problem is when I publish a patch with a SOB line, anyone can take it, "make a derivative work" (so to speak), and submit as his own. The new patch doesn't need to be an improvement, the changes from the original are not even looked upon. Been there BTW. >> +#define AR0521_WIDTH_MIN 8u > > We usually use an uppercase U suffix. >> +#define AR0521_REG_RESET0x301A > > But lowercase hex values. I know, lots of tribal (and sometimes > arbitrary) knowledge :-S Right. Is there a consensus about it? I use lowercase U because it contrasts with "uppercase" digits, and uppercase hex letter for consistency with (decimal) digits, but I can change it if it's only me. >> +regs[0] = AR0521_REG_GREEN1_GAIN; >> +regs[1] = green << 7 | analog; >> +regs[2] = blue << 7 | analog; >> +regs[3] = red << 7 | analog; >> +regs[4] = green << 7 | analog; >> + >> +return ar0521_write_regs(sensor, regs, ARRAY_SIZE(regs)); > > Passing the values in an array, with the first entry being a register > address, is a really weird API. I'd recommend either using regmap (may > be overkill here), or use a write function that takes the register > address and value as separate arguments. If we want to avoid sending the > register address for each write as a performance improvement, we'll have > to figure out what a good API would be to do so, but more importantly, > it would be good to have numbers to justify why this would be needed. It's a slow I^2C device. Doing a single write transfer is faster than a series of transfers, especially on a busy bus. Do I really have to justify why I like a faster and more efficient code? And it's not a big API, it's just a small internal driver subroutine. Would splitting it to several ar0521_write_reg() be better, e.g. more readable? >> +static int ar0521_set_mode(struct ar0521_dev *sensor) >> +{ >> +unsigned int speed_mod = 4 / lanes(sensor); /* 1 with 4 DDR lanes */ >> +u64 pix_clk; >> +u32 pixels, pll2, num, denom, new_total_height, new_pixels; >> +u16 total_width, total_height, x, y, pre, mult, pre2, mult2, >> extra_delay; >> +u16 regs[9]; >> +int ret; >> + >> +/* stop streaming first */ >> +ret = ar0521_write_reg(sensor, AR0521_REG_RESET, >> AR0521_REG_RESET_DEFAULTS); > > set_format isn't supposed to stop streaming implicitly. It should > instead return -EBUSY if the stream if running. It doesn't stop permanently, it's restarted after the registers are updated. No need for -EBUSY here. >> +static int ar0521_s_stream(struct v4l2_subdev *sd, int enable) >> +{ >> +struct ar0521_dev *sensor = to_ar0521_dev(sd); >> +int ret; >> + >> +mutex_lock(&sensor->lock); > > Could you please use runtime PM for power management, enabling the clock > and regulators when starting streaming ? > > I forgot to mention in the review of the DT bindings that regulators > should be specified in DT. Why? The hw using this driver doesn't have capability to disable regulators. If someone produces hw with means to control power, the sw support can be trivially added. When I last checked, we didn't add driver code for functionality for which no hw support exists, did we? -- Krzysztof Hałasa Sieć Badawcza Łukasiewicz Przemysłowy Instytut Automatyki i Pomiarów PIAP Al. Jerozolimskie 202, 02-486 Warszawa
Re: [PATCH v6 4/8] dt-bindings: regulator: Add document for MT6359 regulator
Hi, Rob I am very grateful for the reviewing which addressed my yaml errors. I will check my codebase first and fix the error in the next patch. Thanks. On Tue, 2021-03-16 at 15:28 -0600, Rob Herring wrote: > On Tue, Mar 16, 2021 at 01:35:53AM +0800, Hsin-Hsiung Wang wrote: > > add dt-binding document for MediaTek MT6359 PMIC > > > > Signed-off-by: Hsin-Hsiung Wang > > --- > > changes since v5: > > - no change. > > --- > > .../bindings/regulator/mt6359-regulator.yaml | 169 ++ > > 1 file changed, 169 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml > > > > diff --git > > a/Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml > > b/Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml > > new file mode 100644 > > index ..62ff93eefd39 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml > > @@ -0,0 +1,169 @@ > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/regulator/mt6359-regulator.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: MT6359 Regulator from MediaTek Integrated > > + > > +maintainers: > > + - Hsin-Hsiung Wang > > + > > +description: | > > + List of regulators provided by this controller. It is named > > + according to its regulator type, buck_ and ldo_. > > + MT6359 regulators node should be sub node of the MT6397 MFD node. > > + > > +properties: > > + $nodename: > > +pattern: "^pmic$" > > The errors are because this schema will be applied to every 'pmic' node. > > > + > > + mt6359regulator: > > The node name here should be just 'regulators', but that should be in > the MFD schema and you should remove this level here. So the MFD would > have: > > properties: > regulators: > type: object > $ref: schemas/regulator/mt6359-regulator.yaml# > > > +type: object > > +description: > > + list of regulators provided by this controller. > > + > > +patternProperties: > > And this should be at the top level of this doc. > > > + "^buck_v(s1|gpu11|modem|pu|core|s2|pa|proc2|proc1|core_sshub)$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: > > "^v(s1|gpu11|modem|pu|core|s2|pa|proc2|proc1|core_sshub)$" > > + > > +unevaluatedProperties: false > > + > > + "^ldo_v(ibr|rf12|usb|camio|efuse|xo22)$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: "^v(ibr|rf12|usb|camio|efuse|xo22)$" > > + > > +unevaluatedProperties: false > > + > > + "^ldo_v(rfck|emc|a12|a09|ufs|bbck)$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: "^v(rfck|emc|a12|a09|ufs|bbck)$" > > + > > +unevaluatedProperties: false > > + > > + "^ldo_vcn(18|13|33_1_bt|13_1_wifi|33_2_bt|33_2_wifi)$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: "^vcn(18|13|33_1_bt|13_1_wifi|33_2_bt|33_2_wifi)$" > > + > > +unevaluatedProperties: false > > + > > + "^ldo_vsram_(proc2|others|md|proc1|others_sshub)$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: "^vsram_(proc2|others|md|proc1|others_sshub)$" > > + > > +unevaluatedProperties: false > > + > > + "^ldo_v(fe|bif|io)28$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: "^v(fe|bif|io)28$" > > + > > +unevaluatedProperties: false > > + > > + "^ldo_v(aud|io|aux|rf|m)18$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: "^v(aud|io|aux|rf|m)18$" > > + > > +unevaluatedProperties: false > > + > > + "^ldo_vsim[12]$": > > +type: object > > +$ref: "regulator.yaml#" > > + > > +properties: > > + regulator-name: > > +pattern: "^vsim[12]$" > > + > > +required: > > + - regulator-name > > + > > +unevaluatedProperties: false > > + > > +additionalProperties: false > > + > > +examples: > > + - | > > +pmic { > > + mt6359regulator { > > I prefer to see a single complete example in the MFD schema rather than > piecemeal schemas in each sub schema. > > > +mt6359_vgpu11_buck_reg: buck_vgpu11 { > > + regulator-name = "vgpu11"; > > + regulator-min-microvolt = <40>; > > + regulator-max-microvolt = <1193750>; >
[PATCH] MIPS: ralink: mt7621: add memory detection support
From: Chuanhong Guo mt7621 has the following memory map: 0x0-0x1c00: lower 448m memory 0x1c00-0x200: peripheral registers 0x2000-0x240: higher 64m memory detect_memory_region in arch/mips/kernel/setup.c only adds the first memory region and isn't suitable for 512m memory detection because it may accidentally read the memory area for peripheral registers. This commit adds memory detection capability for mt7621: 1. Add the highmem area when 512m is detected. 2. Guard memcmp from accessing peripheral registers: This only happens when a user decided to change kernel load address to 256m or higher address. Since this is a quite unusual case, we just skip 512m testing and return 256m as memory size. Signed-off-by: Chuanhong Guo [Minor commit message reword, make mt7621_memory_detect static] Signed-off-by: Ilya Lipnitskiy --- arch/mips/include/asm/mach-ralink/mt7621.h | 7 +++--- arch/mips/ralink/common.h | 1 + arch/mips/ralink/mt7621.c | 29 +++--- arch/mips/ralink/of.c | 2 ++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h index e1af1ba50bd8..6bbf082dd149 100644 --- a/arch/mips/include/asm/mach-ralink/mt7621.h +++ b/arch/mips/include/asm/mach-ralink/mt7621.h @@ -24,9 +24,10 @@ #define CHIP_REV_VER_SHIFT 8 #define CHIP_REV_ECO_MASK 0xf -#define MT7621_DRAM_BASE0x0 -#define MT7621_DDR2_SIZE_MIN 32 -#define MT7621_DDR2_SIZE_MAX 256 +#define MT7621_LOWMEM_BASE 0x0 +#define MT7621_LOWMEM_MAX_SIZE 0x1C00 +#define MT7621_HIGHMEM_BASE0x2000 +#define MT7621_HIGHMEM_SIZE0x400 #define MT7621_CHIP_NAME0 0x3637544D #define MT7621_CHIP_NAME1 0x20203132 diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h index 4bc65b7a3241..113dca5ac129 100644 --- a/arch/mips/ralink/common.h +++ b/arch/mips/ralink/common.h @@ -17,6 +17,7 @@ struct ralink_soc_info { unsigned long mem_size; unsigned long mem_size_min; unsigned long mem_size_max; + void (*mem_detect)(void); }; extern struct ralink_soc_info soc_info; diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c index ca0ac607b0f3..d6616b0ad610 100644 --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c @@ -9,7 +9,9 @@ #include #include #include +#include +#include #include #include #include @@ -49,6 +51,8 @@ #define MT7621_GPIO_MODE_SDHCI_SHIFT 18 #define MT7621_GPIO_MODE_SDHCI_GPIO1 +static void *detect_magic __initdata = detect_memory_region; + static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) }; static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) }; static struct rt2880_pmx_func uart3_grp[] = { @@ -110,6 +114,26 @@ phys_addr_t mips_cpc_default_phys_base(void) panic("Cannot detect cpc address"); } +static void __init mt7621_memory_detect(void) +{ + void *dm = &detect_magic; + phys_addr_t size; + + for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) { + if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic))) + break; + } + + if ((size == 256 * SZ_1M) && + (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) && + __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) { + memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE); + memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE); + } else { + memblock_add(MT7621_LOWMEM_BASE, size); + } +} + void __init ralink_of_remap(void) { rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc"); @@ -194,10 +218,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info) (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, (rev & CHIP_REV_ECO_MASK)); - soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN; - soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX; - soc_info->mem_base = MT7621_DRAM_BASE; - + soc_info->mem_detect = mt7621_memory_detect; rt2880_pinmux_data = mt7621_pinmux_data; soc_dev_init(soc_info, rev); diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 8286c3521476..0c5de07da097 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -78,6 +78,8 @@ void __init plat_mem_setup(void) of_scan_flat_dt(early_init_dt_find_memory, NULL); if (memory_dtb) of_scan_flat_dt(early_init_dt_scan_memory, NULL); + else if (soc_info.mem_detect) + soc_info.mem_detect(); else if (soc_info.mem_size) memblock_add(soc_info.mem_base, soc_info.mem_size * SZ_1M); else -- 2.31.0
Re: [PATCH v2] mm: Move mem_init_print_info() into mm_init()
On 2021/3/17 13:48, Christophe Leroy wrote: Le 17/03/2021 à 02:52, Kefeng Wang a écrit : mem_init_print_info() is called in mem_init() on each architecture, and pass NULL argument, so using void argument and move it into mm_init(). Acked-by: Dave Hansen Signed-off-by: Kefeng Wang --- v2: - Cleanup 'str' line suggested by Christophe and ACK arch/alpha/mm/init.c | 1 - arch/arc/mm/init.c | 1 - arch/arm/mm/init.c | 2 -- arch/arm64/mm/init.c | 2 -- arch/csky/mm/init.c | 1 - arch/h8300/mm/init.c | 2 -- arch/hexagon/mm/init.c | 1 - arch/ia64/mm/init.c | 1 - arch/m68k/mm/init.c | 1 - arch/microblaze/mm/init.c | 1 - arch/mips/loongson64/numa.c | 1 - arch/mips/mm/init.c | 1 - arch/mips/sgi-ip27/ip27-memory.c | 1 - arch/nds32/mm/init.c | 1 - arch/nios2/mm/init.c | 1 - arch/openrisc/mm/init.c | 2 -- arch/parisc/mm/init.c | 2 -- arch/powerpc/mm/mem.c | 1 - arch/riscv/mm/init.c | 1 - arch/s390/mm/init.c | 2 -- arch/sh/mm/init.c | 1 - arch/sparc/mm/init_32.c | 2 -- arch/sparc/mm/init_64.c | 1 - arch/um/kernel/mem.c | 1 - arch/x86/mm/init_32.c | 2 -- arch/x86/mm/init_64.c | 2 -- arch/xtensa/mm/init.c | 1 - include/linux/mm.h | 2 +- init/main.c | 1 + mm/page_alloc.c | 10 +- 30 files changed, 7 insertions(+), 42 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 89314651dd62..c2e0b3495c5a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2373,7 +2373,7 @@ extern unsigned long free_reserved_area(void *start, void *end, int poison, const char *s); extern void adjust_managed_page_count(struct page *page, long count); -extern void mem_init_print_info(const char *str); +extern void mem_init_print_info(void); Sorry I didn't see that in previous patch. 'extern' keyword is pointless for function prototypes and is deprecated, you should remove it. That said, Reviewed-by: Christophe Leroy # focussed on powerpc Thanks, let's wait for more feedback from other architectures, if necessary, will send a new one. extern void reserve_bootmem_region(phys_addr_t start, phys_addr_t end); .
RE: [PATCH v3] ASoC: amd: add support for rt5682 codec in machine driver
> On 3/16/21 8:37 AM, Mukunda,Vijendar wrote: > > > > > > On 15/03/21 9:30 pm, Pierre-Louis Bossart wrote: > >> > >>> +static int rt5682_clk_enable(struct snd_pcm_substream *substream) { > >>> + int ret; > >>> + struct snd_soc_pcm_runtime *rtd = > >>> +asoc_substream_to_rtd(substream); > >>> + > >>> + /* > >>> + * Set wclk to 48000 because the rate constraint of this driver > >>> +is > >>> + * 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate > >>> +that is > >>> + * minimum of 64x the LRCLK sample rate." RT5682 is the only > >>> +clk > >>> + * source so for all codecs we have to limit bclk to 64X lrclk. > >>> + */ > >>> + clk_set_rate(rt5682_dai_wclk, 48000); > >>> + clk_set_rate(rt5682_dai_bclk, 48000 * 64); > >>> + ret = clk_prepare_enable(rt5682_dai_bclk); > >>> + if (ret < 0) { > >>> + dev_err(rtd->dev, "can't enable master clock %d\n", ret); > >>> + return ret; > >>> + } > >>> + return ret; > >>> +} > >> > >> Out of curiosity, is there a reason why you use clk_prepare_enable() > >> for the bclk but not for the wclk?These changes were shared by codec > >> vendor as an initial patch. > > We should use clk_prepare_enable() for wclk not for bclk. > > We will update and share the new patch. > > Well the question remains: if you have two clocks and only enable one, why do > you need to get two clocks. > > Also this patch was modeled after the da7219 case, where the same open > applies. The RT5682 could set the wclk and bclk separately. The bclk could set the different ratios (32/64/128/256). However, only the wclk of DAI clock has the .prepare callback function to enable the related power. The next patch should update the clk_prepare_enable() for wclk. > --Please consider the environment before printing this e-mail.
Re: [PATCH] dt-bindings: Clean-up undocumented compatible strings
On 17/03/21 1:19 am, Rob Herring wrote: > Adding checks for undocumented compatible strings reveals a bunch of > warnings in the DT binding examples. Fix the cases which are typos, just > a mismatch between the schema and the example, or aren't documented at all. > In a couple of cases, fixing the compatible revealed some schema errors > which are fixed. > > There's a bunch of others remaining after this which have bindings, but > those aren't converted to schema yet. > > Cc: Stephen Boyd > Cc: Maxime Ripard > Cc: Thierry Reding > Cc: Sam Ravnborg > Cc: Vinod Koul > Cc: Alexandre Belloni > Cc: Jonathan Cameron > Cc: Pavel Machek > Cc: Kishon Vijay Abraham I > Cc: Sebastian Reichel > Cc: Mark Brown > Cc: Greg Kroah-Hartman > Cc: linux-...@vger.kernel.org > Cc: dmaeng...@vger.kernel.org > Cc: linux-...@lists.infradead.org > Cc: linux-...@vger.kernel.org > Cc: linux-l...@vger.kernel.org > Cc: linux...@vger.kernel.org > Cc: linux-ser...@vger.kernel.org > Cc: linux-...@vger.kernel.org > Signed-off-by: Rob Herring Acked-by: Kishon Vijay Abraham I > --- > .../clock/allwinner,sun4i-a10-pll1-clk.yaml | 2 +- > .../bindings/clock/milbeaut-clock.yaml| 12 + > .../bindings/display/brcm,bcm2835-dsi0.yaml | 6 - > .../bindings/display/panel/panel-dpi.yaml | 2 +- > .../devicetree/bindings/dma/qcom,gpi.yaml | 2 +- > .../devicetree/bindings/i3c/i3c.yaml | 7 ++--- > .../iio/adc/brcm,iproc-static-adc.yaml| 5 > .../iio/gyroscope/nxp,fxas21002c.yaml | 2 +- > .../bindings/iio/light/upisemi,us5182.yaml| 4 +-- > .../interrupt-controller/loongson,htpic.yaml | 2 +- > .../devicetree/bindings/leds/leds-lgm.yaml| 26 --- > .../bindings/phy/ti,phy-j721e-wiz.yaml| 2 +- > .../bindings/power/supply/cw2015_battery.yaml | 2 +- > .../bindings/power/supply/power-supply.yaml | 22 > .../devicetree/bindings/serial/serial.yaml| 2 +- > .../bindings/spi/amlogic,meson-gx-spicc.yaml | 4 +-- > .../bindings/spi/spi-controller.yaml | 21 --- > .../devicetree/bindings/spi/spi-mux.yaml | 8 ++ > .../devicetree/bindings/spi/st,stm32-spi.yaml | 6 - > 19 files changed, 58 insertions(+), 79 deletions(-) > > diff --git > a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-pll1-clk.yaml > b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-pll1-clk.yaml > index e9c4cf834aa7..e5d9d45dab8a 100644 > --- > a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-pll1-clk.yaml > +++ > b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-pll1-clk.yaml > @@ -44,7 +44,7 @@ examples: >- | > clk@1c2 { > #clock-cells = <0>; > -compatible = "allwinner,sun4i-a10-pll1"; > +compatible = "allwinner,sun4i-a10-pll1-clk"; > reg = <0x01c2 0x4>; > clocks = <&osc24M>; > clock-output-names = "osc24M"; > diff --git a/Documentation/devicetree/bindings/clock/milbeaut-clock.yaml > b/Documentation/devicetree/bindings/clock/milbeaut-clock.yaml > index 0e8b07710451..6d39344d2b70 100644 > --- a/Documentation/devicetree/bindings/clock/milbeaut-clock.yaml > +++ b/Documentation/devicetree/bindings/clock/milbeaut-clock.yaml > @@ -18,10 +18,12 @@ description: | > > properties: >compatible: > -oneOf: > - - items: > - - enum: > - - socionext,milbeaut-m10v-ccu > +enum: > + - socionext,milbeaut-m10v-ccu > + > + reg: > +maxItems: 1 > + >clocks: > maxItems: 1 > description: external clock > @@ -41,7 +43,7 @@ examples: ># Clock controller node: >- | > m10v-clk-ctrl@1d021000 { > -compatible = "socionext,milbeaut-m10v-clk-ccu"; > +compatible = "socionext,milbeaut-m10v-ccu"; > reg = <0x1d021000 0x4000>; > #clock-cells = <1>; > clocks = <&clki40mhz>; > diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml > b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml > index 55c60919991f..32608578a352 100644 > --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml > +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml > @@ -77,12 +77,6 @@ examples: > > clock-output-names = "dsi1_byte", "dsi1_ddr2", "dsi1_ddr"; > > -pitouchscreen: panel@0 { > -compatible = "raspberrypi,touchscreen"; > -reg = <0>; > - > -/* ... */ > -}; > }; > > ... > diff --git a/Documentation/devicetree/bindings/display/panel/panel-dpi.yaml > b/Documentation/devicetree/bindings/display/panel/panel-dpi.yaml > index 0cd74c8dab42..dae0676b5c6e 100644 > --- a/Documentation/devicetree/bindings/display/panel/panel-dpi.yaml > +++ b/Documentation/devicetree/bindings/display/panel/panel-dpi.yaml > @@ -40,7 +40,7 @@ additionalProperties: false > examples: >- | > panel { > -
[PATCH] virtio_net: replace if (cond) BUG() with BUG_ON()
Fix the following coccicheck warnings: ./drivers/net/virtio_net.c:1551:2-5: WARNING: Use BUG_ON instead of if condition followed by BUG. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong --- drivers/net/virtio_net.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 82e520d..093530b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1545,10 +1545,8 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) else hdr = skb_vnet_hdr(skb); - if (virtio_net_hdr_from_skb(skb, &hdr->hdr, - virtio_is_little_endian(vi->vdev), false, - 0)) - BUG(); + BUG_ON(virtio_net_hdr_from_skb(skb, &hdr->hdr, virtio_is_little_endian(vi->vdev), + false, 0)); if (vi->mergeable_rx_bufs) hdr->num_buffers = 0; -- 1.8.3.1
Re: [PATCH] dt-bindings: Clean-up undocumented compatible strings
On Tue, Mar 16, 2021 at 01:49:18PM -0600, Rob Herring wrote: > Adding checks for undocumented compatible strings reveals a bunch of > warnings in the DT binding examples. Fix the cases which are typos, just > a mismatch between the schema and the example, or aren't documented at all. > In a couple of cases, fixing the compatible revealed some schema errors > which are fixed. > > There's a bunch of others remaining after this which have bindings, but > those aren't converted to schema yet. > > Cc: Stephen Boyd > Cc: Maxime Ripard > Cc: Thierry Reding > Cc: Sam Ravnborg > Cc: Vinod Koul > Cc: Alexandre Belloni > Cc: Jonathan Cameron > Cc: Pavel Machek > Cc: Kishon Vijay Abraham I > Cc: Sebastian Reichel > Cc: Mark Brown > Cc: Greg Kroah-Hartman > Cc: linux-...@vger.kernel.org > Cc: dmaeng...@vger.kernel.org > Cc: linux-...@lists.infradead.org > Cc: linux-...@vger.kernel.org > Cc: linux-l...@vger.kernel.org > Cc: linux...@vger.kernel.org > Cc: linux-ser...@vger.kernel.org > Cc: linux-...@vger.kernel.org > Signed-off-by: Rob Herring Acked-by: Greg Kroah-Hartman
Re: (subset) [PATCH v2 0/5] mtd: spi-nor: Cleanup patches
On Sat, 6 Mar 2021 11:49:57 +0200, Tudor Ambarus wrote: > Various cleanup patches done while reviewing contributions. > > Tudor Ambarus (5): > mtd: spi-nor: core: Advance erase after the erase cmd has been > completed > mtd: spi-nor: core: Add vdbg msg for spi_nor_erase_multi_sectors() > mtd: spi-nor: Get rid of duplicated argument in spi_nor_parse_sfdp() > mtd: spi-nor: Move Software Write Protection logic out of the core > mtd: spi-nor: swp: Drop 'else' after 'return' > > [...] For 2/5: s/%d/%u and then applied to spi-nor/next 1/5, 2/5 and 3/5. [1/5] mtd: spi-nor: core: Advance erase after the erase cmd has been completed https://git.kernel.org/mtd/c/786a0a75d0f3 [2/5] mtd: spi-nor: core: Add vdbg msg for spi_nor_erase_multi_sectors() https://git.kernel.org/mtd/c/875c3d78 [3/5] mtd: spi-nor: Get rid of duplicated argument in spi_nor_parse_sfdp() https://git.kernel.org/mtd/c/a580293a19fc Best regards, -- Tudor Ambarus
Re: [PATCH] dt-bindings: Drop type references on common properties
On Tue, Mar 16, 2021 at 01:48:58PM -0600, Rob Herring wrote: > Users of common properties shouldn't have a type definition as the > common schemas already have one. Drop all the unnecessary type > references in the tree. > > A meta-schema update to catch these is pending. > > Cc: Nicolas Saenz Julienne > Cc: Maxime Ripard > Cc: Linus Walleij > Cc: Bartosz Golaszewski > Cc: Bjorn Andersson > Cc: Krzysztof Kozlowski > Cc: Marc Kleine-Budde > Cc: "David S. Miller" > Cc: Jakub Kicinski > Cc: Srinivas Kandagatla > Cc: Ohad Ben-Cohen > Cc: Mark Brown > Cc: Cheng-Yi Chiang > Cc: Benson Leung > Cc: Zhang Rui > Cc: Daniel Lezcano > Cc: Greg Kroah-Hartman > Cc: Stefan Wahren > Cc: Masahiro Yamada > Cc: Odelu Kukatla > Cc: Alex Elder > Cc: Suman Anna > Cc: Kuninori Morimoto > Cc: Dmitry Baryshkov > Cc: linux-g...@vger.kernel.org > Cc: linux...@vger.kernel.org > Cc: linux-...@vger.kernel.org > Cc: net...@vger.kernel.org > Cc: linux-remotep...@vger.kernel.org > Cc: alsa-de...@alsa-project.org > Cc: linux-...@vger.kernel.org > Signed-off-by: Rob Herring > --- > .../bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml | 5 + > Documentation/devicetree/bindings/arm/cpus.yaml | 2 -- > .../bindings/display/allwinner,sun4i-a10-tcon.yaml | 1 - > .../devicetree/bindings/gpio/socionext,uniphier-gpio.yaml| 3 +-- > .../devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml | 1 - > .../devicetree/bindings/interconnect/qcom,rpmh.yaml | 1 - > .../bindings/memory-controllers/nvidia,tegra210-emc.yaml | 2 +- > Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml | 1 - > Documentation/devicetree/bindings/net/qcom,ipa.yaml | 1 - > Documentation/devicetree/bindings/nvmem/nvmem-consumer.yaml | 2 -- > .../devicetree/bindings/remoteproc/ti,omap-remoteproc.yaml | 2 +- > Documentation/devicetree/bindings/sound/ak4642.yaml | 2 -- > .../devicetree/bindings/sound/google,cros-ec-codec.yaml | 2 +- > Documentation/devicetree/bindings/sound/renesas,rsnd.yaml| 1 - > .../devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml | 1 - > Documentation/devicetree/bindings/usb/usb.yaml | 1 - > 16 files changed, 5 insertions(+), 23 deletions(-) Acked-by: Greg Kroah-Hartman
Re: [PATCH] mtd: spi-nor: Update comment about the default flash parameters
On Mon, 15 Mar 2021 07:56:34 +0200, Tudor Ambarus wrote: > s/legacy/default. spi_nor_info_init_params initializes some default > flash parameters and settings that can be overwritten when parsing > SFDP, or by fixup hooks. There's nothing legacy about them, they are > just some default settings, if not otherwise discovered or specified. Applied to spi-nor/next, thanks! [1/1] mtd: spi-nor: Update comment about the default flash parameters https://git.kernel.org/mtd/c/79321e752aff Best regards, -- Tudor Ambarus
Re: [PATCH v2] scsi: dt-bindings: ufs: Add sm8250, sm8350 compatible strings
Hello Martin, On 16-03-21, 21:21, Martin K. Petersen wrote: > > Vinod, > > >> Document "qcom,sm8250-ufshc" and "qcom,sm8350-ufshc" compatible string. > >> Use of "qcom,sm8250-ufshc" is already present upstream, so add misiing > >> documentation. "qcom,sm8350-ufshc" is for UFS HC found in SM8350 SoC. > > > > Gentle reminder for this patch, Rob has acked this > > Was not really expecting a DT patch to be routed through SCSI. But no > worries. I've queued it up. Thank you. You can blame MAINTAINERS for pointing it to you :) Typically DT binding go thru subsystem and dts thru soc trees -- ~Vinod
[syzbot] KMSAN: uninit-value in iptable_mangle_hook (5)
Hello, syzbot found the following issue on: HEAD commit:29ad81a1 arch/x86: add missing include to sparsemem.h git tree: https://github.com/google/kmsan.git master console output: https://syzkaller.appspot.com/x/log.txt?x=179b38f6d0 kernel config: https://syzkaller.appspot.com/x/.config?x=8b976581f6bd1e7d dashboard link: https://syzkaller.appspot.com/bug?extid=9b5e12c49c015d4c1aeb compiler: Debian clang version 11.0.1-2 Unfortunately, I don't have any reproducer for this issue yet. IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+9b5e12c49c015d4c1...@syzkaller.appspotmail.com netlink: 24 bytes leftover after parsing attributes in process `syz-executor.4'. = BUG: KMSAN: uninit-value in ipt_mangle_out net/ipv4/netfilter/iptable_mangle.c:61 [inline] BUG: KMSAN: uninit-value in iptable_mangle_hook+0x75a/0x8c0 net/ipv4/netfilter/iptable_mangle.c:81 CPU: 1 PID: 25792 Comm: syz-executor.4 Not tainted 5.11.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x21c/0x280 lib/dump_stack.c:120 kmsan_report+0xfb/0x1e0 mm/kmsan/kmsan_report.c:118 __msan_warning+0x5f/0xa0 mm/kmsan/kmsan_instr.c:197 ipt_mangle_out net/ipv4/netfilter/iptable_mangle.c:61 [inline] iptable_mangle_hook+0x75a/0x8c0 net/ipv4/netfilter/iptable_mangle.c:81 nf_hook_entry_hookfn include/linux/netfilter.h:136 [inline] nf_hook_slow+0x17b/0x460 net/netfilter/core.c:589 nf_hook include/linux/netfilter.h:256 [inline] __ip_local_out+0x78c/0x840 net/ipv4/ip_output.c:115 ip_local_out+0xa1/0x1e0 net/ipv4/ip_output.c:124 iptunnel_xmit+0x931/0xf20 net/ipv4/ip_tunnel_core.c:82 udp_tunnel_xmit_skb+0x526/0x640 net/ipv4/udp_tunnel_core.c:190 geneve_xmit_skb drivers/net/geneve.c:959 [inline] geneve_xmit+0x209e/0x3c20 drivers/net/geneve.c:1059 __netdev_start_xmit include/linux/netdevice.h:4778 [inline] netdev_start_xmit include/linux/netdevice.h:4792 [inline] xmit_one+0x2b6/0x760 net/core/dev.c:3574 dev_hard_start_xmit net/core/dev.c:3590 [inline] __dev_queue_xmit+0x3426/0x45c0 net/core/dev.c:4151 dev_queue_xmit+0x4b/0x60 net/core/dev.c:4184 packet_snd net/packet/af_packet.c:3006 [inline] packet_sendmsg+0x8778/0x9a60 net/packet/af_packet.c:3031 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg net/socket.c:672 [inline] sys_sendmsg+0xcfc/0x12f0 net/socket.c:2345 ___sys_sendmsg net/socket.c:2399 [inline] __sys_sendmsg+0x714/0x830 net/socket.c:2432 __do_sys_sendmsg net/socket.c:2441 [inline] __se_sys_sendmsg+0x97/0xb0 net/socket.c:2439 __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2439 do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x465f69 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:7fae1692d188 EFLAGS: 0246 ORIG_RAX: 002e RAX: ffda RBX: 0056bf60 RCX: 00465f69 RDX: 8844 RSI: 25c0 RDI: 0003 RBP: 004bfa8f R08: R09: R10: R11: 0246 R12: 0056bf60 R13: 00a9fb1f R14: 7fae1692d300 R15: 00022000 Uninit was stored to memory at: kmsan_save_stack_with_flags mm/kmsan/kmsan.c:121 [inline] kmsan_internal_chain_origin+0xad/0x130 mm/kmsan/kmsan.c:289 __msan_chain_origin+0x57/0xa0 mm/kmsan/kmsan_instr.c:147 iptunnel_xmit+0xbd6/0xf20 net/ipv4/ip_tunnel_core.c:76 udp_tunnel_xmit_skb+0x526/0x640 net/ipv4/udp_tunnel_core.c:190 geneve_xmit_skb drivers/net/geneve.c:959 [inline] geneve_xmit+0x209e/0x3c20 drivers/net/geneve.c:1059 __netdev_start_xmit include/linux/netdevice.h:4778 [inline] netdev_start_xmit include/linux/netdevice.h:4792 [inline] xmit_one+0x2b6/0x760 net/core/dev.c:3574 dev_hard_start_xmit net/core/dev.c:3590 [inline] __dev_queue_xmit+0x3426/0x45c0 net/core/dev.c:4151 dev_queue_xmit+0x4b/0x60 net/core/dev.c:4184 packet_snd net/packet/af_packet.c:3006 [inline] packet_sendmsg+0x8778/0x9a60 net/packet/af_packet.c:3031 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg net/socket.c:672 [inline] sys_sendmsg+0xcfc/0x12f0 net/socket.c:2345 ___sys_sendmsg net/socket.c:2399 [inline] __sys_sendmsg+0x714/0x830 net/socket.c:2432 __do_sys_sendmsg net/socket.c:2441 [inline] __se_sys_sendmsg+0x97/0xb0 net/socket.c:2439 __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2439 do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Uninit was created at: kmsan_save_stack_with_flags mm/kmsan/kmsan.c:121 [inline] kmsan_internal_poison_shadow+0x5c/0xf0 mm/kmsan/kmsan.c:104 kmsan_slab_alloc+0x8d/0xe0 mm/kmsan/kmsan_hooks.c:76 slab_alloc_node mm/sl
Re: [PATCH v2] mm: Move mem_init_print_info() into mm_init()
Le 17/03/2021 à 02:52, Kefeng Wang a écrit : mem_init_print_info() is called in mem_init() on each architecture, and pass NULL argument, so using void argument and move it into mm_init(). Acked-by: Dave Hansen Signed-off-by: Kefeng Wang --- v2: - Cleanup 'str' line suggested by Christophe and ACK arch/alpha/mm/init.c | 1 - arch/arc/mm/init.c | 1 - arch/arm/mm/init.c | 2 -- arch/arm64/mm/init.c | 2 -- arch/csky/mm/init.c | 1 - arch/h8300/mm/init.c | 2 -- arch/hexagon/mm/init.c | 1 - arch/ia64/mm/init.c | 1 - arch/m68k/mm/init.c | 1 - arch/microblaze/mm/init.c| 1 - arch/mips/loongson64/numa.c | 1 - arch/mips/mm/init.c | 1 - arch/mips/sgi-ip27/ip27-memory.c | 1 - arch/nds32/mm/init.c | 1 - arch/nios2/mm/init.c | 1 - arch/openrisc/mm/init.c | 2 -- arch/parisc/mm/init.c| 2 -- arch/powerpc/mm/mem.c| 1 - arch/riscv/mm/init.c | 1 - arch/s390/mm/init.c | 2 -- arch/sh/mm/init.c| 1 - arch/sparc/mm/init_32.c | 2 -- arch/sparc/mm/init_64.c | 1 - arch/um/kernel/mem.c | 1 - arch/x86/mm/init_32.c| 2 -- arch/x86/mm/init_64.c| 2 -- arch/xtensa/mm/init.c| 1 - include/linux/mm.h | 2 +- init/main.c | 1 + mm/page_alloc.c | 10 +- 30 files changed, 7 insertions(+), 42 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 89314651dd62..c2e0b3495c5a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2373,7 +2373,7 @@ extern unsigned long free_reserved_area(void *start, void *end, int poison, const char *s); extern void adjust_managed_page_count(struct page *page, long count); -extern void mem_init_print_info(const char *str); +extern void mem_init_print_info(void); Sorry I didn't see that in previous patch. 'extern' keyword is pointless for function prototypes and is deprecated, you should remove it. That said, Reviewed-by: Christophe Leroy # focussed on powerpc extern void reserve_bootmem_region(phys_addr_t start, phys_addr_t end);
RE: Re: [PATCH v5 05/10] scsi: ufshpb: Region inactivation in host mode
>> >> --- >> >> drivers/scsi/ufs/ufshpb.c | 14 ++ >> >> drivers/scsi/ufs/ufshpb.h | 1 + >> >> 2 files changed, 15 insertions(+) >> >> >> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c >> >> index 6f4fd22eaf2f..0744feb4d484 100644 >> >> --- a/drivers/scsi/ufs/ufshpb.c >> >> +++ b/drivers/scsi/ufs/ufshpb.c >> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct >> >> ufshpb_lu *hpb, >> >> >> >> blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn); >> >> >> >> +hpb->stats.umap_req_cnt++; >> >> return 0; >> >> } >> >> >> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct >> >> ufshpb_lu *hpb, >> >> return -EAGAIN; >> >> } >> >> >> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb, >> >> +struct ufshpb_region *rgn) >> >> +{ >> >> +return ufshpb_issue_umap_req(hpb, rgn); >> >> +} >> >> + >> >> static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb) >> >> { >> >> return ufshpb_issue_umap_req(hpb, NULL); >> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct >> >> ufshpb_lu *hpb, >> >> struct ufshpb_subregion *srgn; >> >> int srgn_idx; >> >> >> >> + >> >> +if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn)) >> > >> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ >> > disabled, >> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(), >> > below >> > warning shall pop up every time, fix it? >> > >> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk >> > *bd_disk, >> > struct request *rq, int at_head, >> > rq_end_io_fn *done) >> > { >> > WARN_ON(irqs_disabled()); >> > ... >> > >> >> Moreover, since we are here with rgn_state_lock held and IRQ >> disabled, >> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache, >> GFP_KERNEL) >> has the GFP_KERNEL flag, scheduling while atomic??? > I think your comment applies to ufshpb_issue_umap_all_req as well, > Which is called from slave_configure/scsi_add_lun. > > Since the host-mode series is utilizing the framework laid by the > device-mode, > Maybe you can add this comment to Daejun's last version? Hi Avri, Can Guo I think ufshpb_issue_umap_single_req() can be moved to end of ufshpb_evict_region(). Then we can avoid rgn_state_lock when it sends unmap command. >>> >>> I am not the expert here, please you two fix it. I am just reporting >>> what can be wrong. Anyways, ufshpb_issue_umap_single_req() should not >>> be called with rgn_state_lock held - think about below (another >>> deadly) >>> scenario. >>> >>> lock(rgn_state_lock) >>> ufshpb_issue_umap_single_req() >>> ufshpb_prep() >>>lock(rgn_state_lock) <-- recursive spin_lock >>> >>> BTW, @Daejun shouldn't we stop passthrough cmds from stepping >>> into ufshpb_prep()? In current code, you are trying to use below >>> check to block cmds other than write/discard/read, but a passthrough >>> cmd can not be blocked by the check. >>> >>> if (!ufshpb_is_write_or_discard_cmd(cmd) && >>> !ufshpb_is_read_cmd(cmd) ) >>> return 0; >> >> I found this problem too. I fixed it and submit next patch. > >You mean in V30, which has not been uploaded yet, right? Yes, it is about v30. Thanks, Daejun >Thanks, >Can Guo. > >> >> if (blk_rq_is_scsi(cmd->request) || >> (!ufshpb_is_write_or_discard_cmd(cmd) && >> !ufshpb_is_read_cmd(cmd))) >> return 0; >> >> >> Thanks, >> Daejun >> >>> Thanks, >>> Can Guo. >>> Thanks, Daejun > Thanks, > Avri > >> >> Can Guo. >> >> > Thanks. >> > Can Guo. >> > >> >> +return; >> >> + >> >> lru_info = &hpb->lru_info; >> >> >> >> dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", >> >> rgn->rgn_idx); >> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt); >> >> ufshpb_sysfs_attr_show_func(rb_active_cnt); >> >> ufshpb_sysfs_attr_show_func(rb_inactive_cnt); >> >> ufshpb_sysfs_attr_show_func(map_req_cnt); >> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt); >> >> >> >> static struct attribute *hpb_dev_stat_attrs[] = { >> >> &dev_attr_hit_cnt.attr, >> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] = >> >> { >> >> &dev_attr_rb_active_cnt.attr, >> >> &dev_attr_rb_inactive_cnt.attr, >> >> &dev_attr_map_req_cnt.attr, >> >> +&dev_attr_umap_req_cnt.attr, >> >> NULL, >
[PATCH] KVM: arm: memcg awareness
From: Wanpeng Li KVM allocations in the arm kvm code which are tied to the life of the VM process should be charged to the VM process's cgroup. This will help the memcg controler to do the right decisions. Signed-off-by: Wanpeng Li --- arch/arm64/kvm/arm.c | 5 +++-- arch/arm64/kvm/hyp/pgtable.c | 4 ++-- arch/arm64/kvm/mmu.c | 4 ++-- arch/arm64/kvm/pmu-emul.c | 2 +- arch/arm64/kvm/reset.c | 2 +- arch/arm64/kvm/vgic/vgic-debug.c | 2 +- arch/arm64/kvm/vgic/vgic-init.c| 2 +- arch/arm64/kvm/vgic/vgic-irqfd.c | 2 +- arch/arm64/kvm/vgic/vgic-its.c | 14 +++--- arch/arm64/kvm/vgic/vgic-mmio-v3.c | 2 +- arch/arm64/kvm/vgic/vgic-v4.c | 2 +- 11 files changed, 21 insertions(+), 20 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 7f06ba7..8040874 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -278,9 +278,10 @@ long kvm_arch_dev_ioctl(struct file *filp, struct kvm *kvm_arch_alloc_vm(void) { if (!has_vhe()) - return kzalloc(sizeof(struct kvm), GFP_KERNEL); + return kzalloc(sizeof(struct kvm), GFP_KERNEL_ACCOUNT); - return vzalloc(sizeof(struct kvm)); + return __vmalloc(sizeof(struct kvm), + GFP_KERNEL_ACCOUNT | __GFP_ZERO); } void kvm_arch_free_vm(struct kvm *kvm) diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 926fc07..a0845d3 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -366,7 +366,7 @@ static int hyp_map_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, if (WARN_ON(level == KVM_PGTABLE_MAX_LEVELS - 1)) return -EINVAL; - childp = (kvm_pte_t *)get_zeroed_page(GFP_KERNEL); + childp = (kvm_pte_t *)get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!childp) return -ENOMEM; @@ -401,7 +401,7 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits) { u64 levels = ARM64_HW_PGTABLE_LEVELS(va_bits); - pgt->pgd = (kvm_pte_t *)get_zeroed_page(GFP_KERNEL); + pgt->pgd = (kvm_pte_t *)get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!pgt->pgd) return -ENOMEM; diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 8711894..8c9dc49 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -370,7 +370,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu) return -EINVAL; } - pgt = kzalloc(sizeof(*pgt), GFP_KERNEL); + pgt = kzalloc(sizeof(*pgt), GFP_KERNEL_ACCOUNT); if (!pgt) return -ENOMEM; @@ -1244,7 +1244,7 @@ int kvm_mmu_init(void) goto out; } - hyp_pgtable = kzalloc(sizeof(*hyp_pgtable), GFP_KERNEL); + hyp_pgtable = kzalloc(sizeof(*hyp_pgtable), GFP_KERNEL_ACCOUNT); if (!hyp_pgtable) { kvm_err("Hyp mode page-table not allocated\n"); err = -ENOMEM; diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index e32c6e1..00cf750 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -967,7 +967,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) mutex_lock(&vcpu->kvm->lock); if (!vcpu->kvm->arch.pmu_filter) { - vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL); + vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT); if (!vcpu->kvm->arch.pmu_filter) { mutex_unlock(&vcpu->kvm->lock); return -ENOMEM; diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index bd354cd..3cbcf6b 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -110,7 +110,7 @@ static int kvm_vcpu_finalize_sve(struct kvm_vcpu *vcpu) vl > SVE_VL_ARCH_MAX)) return -EIO; - buf = kzalloc(SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl)), GFP_KERNEL); + buf = kzalloc(SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl)), GFP_KERNEL_ACCOUNT); if (!buf) return -ENOMEM; diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index f38c40a..e6a01f2 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -92,7 +92,7 @@ static void *vgic_debug_start(struct seq_file *s, loff_t *pos) goto out; } - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc(sizeof(*iter), GFP_KERNEL_ACCOUNT); if (!iter) { iter = ERR_PTR(-ENOMEM); goto out; diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 052917d..27d1513 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -134,7 +134,7 @@ static int kvm_v
Re: A problem of Intel IOMMU hardware ?
> On Mar 16, 2021, at 8:16 PM, Longpeng (Mike, Cloud Infrastructure Service > Product Dept.) wrote: > > Hi guys, > > We find the Intel iommu cache (i.e. iotlb) maybe works wrong in a special > situation, it would cause DMA fails or get wrong data. > > The reproducer (based on Alex's vfio testsuite[1]) is in attachment, it can > reproduce the problem with high probability (~50%). I saw Lu replied, and he is much more knowledgable than I am (I was just intrigued by your email). However, if I were you I would try also to remove some “optimizations” to look for the root-cause (e.g., use domain specific invalidations instead of page-specific). The first thing that comes to my mind is the invalidation hint (ih) in iommu_flush_iotlb_psi(). I would remove it to see whether you get the failure without it. signature.asc Description: Message signed with OpenPGP
Re: [net PATCH 3/9] octeontx2-af: Do not allocate memory for devlink private
On Wed, Mar 17, 2021 at 1:57 AM Jakub Kicinski wrote: > > On Tue, 16 Mar 2021 23:33:40 +0530 sundeep subbaraya wrote: > > On Tue, Mar 16, 2021 at 10:53 PM Jakub Kicinski wrote: > > > > > > On Tue, 16 Mar 2021 14:57:07 +0530 Hariprasad Kelam wrote: > > > > From: Subbaraya Sundeep > > > > > > > > Memory for driver private structure rvu_devlink is > > > > also allocated during devlink_alloc. Hence use > > > > the allocated memory by devlink_alloc and access it > > > > by devlink_priv call. > > > > > > > > Fixes: fae06da4("octeontx2-af: Add devlink suppoort to af driver") > > > > Signed-off-by: Subbaraya Sundeep > > > > Signed-off-by: Hariprasad Kelam > > > > Signed-off-by: Sunil Kovvuri Goutham > > > > > > Does it fix any bug? Looks like a coding improvement. > > > > Without this we cannot fetch our private struct 'rvu_devlink' from any > > of the functions in devlink_ops which may get added in future. > > "which may get added in future" does not sound like it's fixing > an existing problem to me :( > > If you have particular case where the existing setup is problematic > please describe it in more detail, or mention what other fix depends > on this patch. Otherwise sending this one patch for net-next would > be better IMHO. Sure will send this one patch to net-next. Thanks, Sundeep
Re: [PATCH 04/13] lib: introduce BITS_{FIRST,LAST} macro
On Tue, Mar 16, 2021 at 01:42:45PM +0200, Andy Shevchenko wrote: > On Tue, Mar 16, 2021 at 09:35:35AM +0100, Rasmus Villemoes wrote: > > On 16/03/2021 02.54, Yury Norov wrote: > > > BITMAP_{LAST,FIRST}_WORD_MASK() in linux/bitmap.h duplicates the > > > functionality of GENMASK(). The scope of BITMAP* macros is wider > > > than just bitmaps. This patch defines 4 new macros: BITS_FIRST(), > > > BITS_LAST(), BITS_FIRST_MASK() and BITS_LAST_MASK() in linux/bits.h > > > on top of GENMASK() and replaces BITMAP_{LAST,FIRST}_WORD_MASK() > > > to avoid duplication and increase the scope of the macros. > > > > > > This change doesn't affect code generation. On ARM64: > > > scripts/bloat-o-meter vmlinux.before vmlinux > > > add/remove: 1/2 grow/shrink: 2/0 up/down: 17/-16 (1) > > > Function old new delta > > > ethtool_get_drvinfo 900 908 +8 > > > e843419@0cf2_0001309d_7f0 - 8 +8 > > > vermagic 48 49 +1 > > > e843419@0d45_000138bb_f68 8 - -8 > > > e843419@0cc9_00012bce_198c 8 - -8 > > > > [what on earth are those weird symbols?] > > > > > > > diff --git a/include/linux/bits.h b/include/linux/bits.h > > > index 7f475d59a097..8c191c29506e 100644 > > > --- a/include/linux/bits.h > > > +++ b/include/linux/bits.h > > > @@ -37,6 +37,12 @@ > > > #define GENMASK(h, l) \ > > > (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l)) > > > > > > +#define BITS_FIRST(nr) GENMASK((nr), 0) > > > +#define BITS_LAST(nr)GENMASK(BITS_PER_LONG - 1, (nr)) > > > + > > > +#define BITS_FIRST_MASK(nr) BITS_FIRST((nr) % BITS_PER_LONG) > > > +#define BITS_LAST_MASK(nr) BITS_LAST((nr) % BITS_PER_LONG) > > > > I don't think it's a good idea to propagate the unusual closed-range > > semantics of GENMASK to those wrappers. Almost all C and kernel code > > uses the 'inclusive lower bound, exclusive upper bound', and I'd expect > > BITS_FIRST(5) to result in a word with five bits set, not six. So I > > think these changes as-is make the code much harder to read and understand. > > > > Regardless, please add some comments on the valid input ranges to the > > macros, whether that ends up being 0 <= nr < BITS_PER_LONG or 0 < nr <= > > BITS_PER_LONG or whatnot. > > > > It would also be much easier to review if you just redefined the > > BITMAP_LAST_WORD_MASK macros etc. in terms of these new things, so you > > wouldn't have to do a lot of mechanical changes at the same time as > > introducing the new ones - especially when those mechanical changes > > involve adding a "minus 1" everywhere. > > I tend to agree with Rasmus here. OK. All this plus terrible GENMASK(high, low) design, when high goes first, makes me feel like we need to deprecate GENMASK and propose a new interface. What do you think about this: BITS_FIRST(bitnum) -> [0, bitnum) BITS_LAST(bitnum) -> [bitnum, BITS_PER_LONG) BITS_RANGE(begin, end) -> [begin, end) We can pick BITS_{LAST,FIRST} implementation from existing BITMAP_*_WORD_MASK analogues, and make the BITS_RANGE like: #define BITS_RANGE(begin, end) BITS_FIRST(end) & BITS_LAST(begin) Regarding BITMAP_*_WORD_MASK, I can save them in bitmap.h as aliases to BITS_{LAST,FIRST} to avoid massive renaming. (Should I?) Would this all work for you?
Re: [PATCH v7 25/38] iio/scmi: port driver to the new scmi_sensor_proto_ops interface
Hi Christian, Thanks for the detailed explanation. Sounds good to me. Thanks, Jyoti On Tue, Mar 16, 2021 at 3:22 PM Cristian Marussi wrote: > > Hi Jyoti, > > On Tue, Mar 16, 2021 at 10:51:48AM -0700, Jyoti Bhayana wrote: > > Hi Christian, > > > > Thanks for porting this driver to the new interface. I have two questions: > > > > 1) In the following code snippet, can the sensor_ops be made as part > > of struct scmi_iio_priv as scmi_protocol_handle is also part of that > > struct. Not sure if there are any particular reasons for having the > > protocol handle as part of the struct but the sensor_ops as global? > > > > > +static const struct scmi_sensor_proto_ops *sensor_ops; > > >+ > > >.struct scmi_iio_priv { > > >- struct scmi_handle *handle; > > >+ struct scmi_protocol_handle *ph; > > > const struct scmi_sensor_info *sensor_info; > > > struct iio_dev *indio_dev; > > > > So, the protocol_handle represents a reference to an instance of > the sensor protocol initialized against the specific SCMI platform > instance referred by the handle provided in the probe: so that if you > should have multiple SCMI platforms defined in the DT, this driver > (as all SCMI drivers) would be probed multiple times each time with a > different handle and it would obtain a different protocol_handle each > time it issued a probe() => devm_protocol_get(). > For this reason the obtained protocol_handle cannot be kept as a global > and it seemed a good fit to stay in the existent scmi_iio_priv. > > On the other side, the sensor_ops are just plain function pointers (as > they were before), so on any possible probe they are returned the same > (for the same proto): it is indeed the specified protocol_handle used > at invocation time that determines against which instance they actually > operates (if multiple instances present at all); so the sensor_ops seemed > a good fit for a global, also because that way tehy are more easily > accessible throughout the driver. > > Does it make sense ? > > > 2) Looks like the event notifier registration is SCMI device managed > > and that's why there is no call to unregister. I am assuming that you > > have tested the logic of inserting the module, removing it and then > > again inserting it to make sure that when the event is registered a > > second time , the logic is all good. > > > >> ret = handle->notify_ops->devm_event_notifier_register(sdev, > > > > Sure, I tested load/unload in general for also other SCMI drivers just > to be sure not to have broken completely the world with this series. > > Please find below a load/unload/load sequence for scmi_iio.ko. > (there are 2 emulated sensors, only one is timestamped) > > Thanks > > Cristian > > --- > > (debian-arm64)root@debarm64:~# ls /sys/bus/iio/devices/ > (debian-arm64)root@debarm64:~# insmod ./scmi_iio.ko > (debian-arm64)root@debarm64:~# ls /sys/bus/iio/devices/ > iio:device0 iio:device1 > (debian-arm64)root@debarm64:~# cat /sys/bus/iio/devices/iio\:device0/name > emu8_accel > (debian-arm64)root@debarm64:~# cat /sys/bus/iio/devices/iio\:device1/name > emu9_gyro > (debian-arm64)root@debarm64:~# /root/iio_generic_buffer -a -c -1 -g -l 100 -N > 0 > iio device number being used is 0 > trigger-less mode selected > Enabling all channels > Enabling: in_accel_x_en > Enabling: in_accel_z_en > Enabling: in_timestamp_en > Enabling: in_accel_y_en > -7737 -7729 -7721 16725578467193651200.00 > -7736 -7728 -7720 16725578467193651200.00 > -7735 -7727 -7719 16725578467193651200.00 > -7734 -7726 -7718 16725578467193651200.00 > -7733 -7725 -7717 16725578467193651200.00 > -7732 -7724 -7716 16725578467193651200.00 > -7731 -7723 -7715 16725578467193651200.00 > -7730 -7722 -7714 17725578795097784320.00 > -7729 -7721 -7713 17725578795097784320.00 > -7728 -7720 -7712 17725578795097784320.00 > -7727 -7719 -7711 17725578795097784320.00 > -7726 -7718 -7710 17725578795097784320.00 > -7725 -7717 -7709 17725578795097784320.00 > -7724 -7716 -7708 17725578795097784320.00 > -7723 -7715 -7707 17725578795097784320.00 > -7722 -7714 -7706 17725578795097784320.00 > -7721 -7713 -7705 17725578795097784320.00 > ^CCaught signal 2 > Disabling: in_accel_x_en > Disabling: in_accel_z_en > Disabling: in_timestamp_en > Disabling: in_accel_y_en > (debian-arm64)root@debarm64:~# /root/iio_generic_buffer -a -c -1 -g -l 100 -N > 1 > iio device number being used is 1 > trigger-less mode selected > Enabling all channels > Enabling: in_accel_x_en > Enabling: in_accel_z_en > Enabling: in_timestamp_en > Enabling: in_accel_y_en > -3583 -3574 -3565 270679244800.00 > -3582 -3573 -3564 270780203008.00 > -3581 -3572 -3563 270880358400.00 > -3580 -3571 -3562 270980431872.00 > -3579 -3570 -3561 271080521728.00 > -3578 -3569 -3560 271180611584.00 > -3577 -3568 -3559 271280685056.00 > -3576 -3567 -3558 271380774912.00 > -3575 -3566 -3557 271480848384.00 > -3574 -3565 -3556