diff options
| author | Breno Leitao <leitao@debian.org> | 2026-08-05 07:52:36 -0700 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-08-10 11:47:20 -1000 |
| commit | a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656 (patch) | |
| tree | 39f5b258386e1127d253d293194e9a2991bf3c34 /arch/hexagon/mm/cache.c | |
| download | linux-stable-a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656.tar.gz linux-stable-a5bde5d8fde8a8cb28e59a672d5ddc5b9c1e7656.zip | |
workqueue: skip the node_nr_active update for non-unbound workqueuesgrafted
apply_wqattrs_commit() updates node_nr_active->max unconditionally.
wq->node_nr_active[] is only allocated for unbound workqueues, so guard
the call before per-cpu workqueues start using this path.
No functional change: only unbound workqueues reach apply_wqattrs_*()
today.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/hexagon/mm/cache.c')
| -rw-r--r-- | arch/hexagon/mm/cache.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/arch/hexagon/mm/cache.c b/arch/hexagon/mm/cache.c new file mode 100644 index 000000000..7e46f40c8 --- /dev/null +++ b/arch/hexagon/mm/cache.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Cache management functions for Hexagon + * + * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + */ + +#include <linux/mm.h> +#include <asm/cacheflush.h> +#include <asm/hexagon_vm.h> + +#define spanlines(start, end) \ + (((end - (start & ~(LINESIZE - 1))) >> LINEBITS) + 1) + +void flush_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long lines = spanlines(start, end-1); + unsigned long i, flags; + + start &= ~(LINESIZE - 1); + + local_irq_save(flags); + + for (i = 0; i < lines; i++) { + __asm__ __volatile__ ( + " dccleaninva(%0); " + : + : "r" (start) + ); + start += LINESIZE; + } + local_irq_restore(flags); +} + +void flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long lines = spanlines(start, end-1); + unsigned long i, flags; + + start &= ~(LINESIZE - 1); + + local_irq_save(flags); + + for (i = 0; i < lines; i++) { + __asm__ __volatile__ ( + " dccleana(%0); " + " icinva(%0); " + : + : "r" (start) + ); + start += LINESIZE; + } + __asm__ __volatile__ ( + "isync" + ); + local_irq_restore(flags); +} +EXPORT_SYMBOL(flush_icache_range); + +void hexagon_clean_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long lines = spanlines(start, end-1); + unsigned long i, flags; + + start &= ~(LINESIZE - 1); + + local_irq_save(flags); + + for (i = 0; i < lines; i++) { + __asm__ __volatile__ ( + " dccleana(%0); " + : + : "r" (start) + ); + start += LINESIZE; + } + local_irq_restore(flags); +} + +void hexagon_inv_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long lines = spanlines(start, end-1); + unsigned long i, flags; + + start &= ~(LINESIZE - 1); + + local_irq_save(flags); + + for (i = 0; i < lines; i++) { + __asm__ __volatile__ ( + " dcinva(%0); " + : + : "r" (start) + ); + start += LINESIZE; + } + local_irq_restore(flags); +} + + + + +/* + * This is just really brutal and shouldn't be used anyways, + * especially on V2. Left here just in case. + */ +void flush_cache_all_hexagon(void) +{ + unsigned long flags; + local_irq_save(flags); + __vmcache_ickill(); + __vmcache_dckill(); + __vmcache_l2kill(); + local_irq_restore(flags); + mb(); +} + +void copy_to_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long vaddr, void *dst, void *src, int len) +{ + memcpy(dst, src, len); + if (vma->vm_flags & VM_EXEC) { + flush_icache_range((unsigned long) dst, + (unsigned long) dst + len); + } +} |
