diff options
| author | Paul E. McKenney <paulmck@kernel.org> | 2026-08-14 15:43:51 -0700 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@kernel.org> | 2026-08-14 15:43:51 -0700 |
| commit | 9cc63f8bcd560c760d0b12e15bba8f81c86237cf (patch) | |
| tree | 3b5269b1bcf6714171754946367c51e0590f64da /sound/soc/sof/sof-utils.c | |
| download | linux-stable-9cc63f8bcd560c760d0b12e15bba8f81c86237cf.tar.gz linux-stable-9cc63f8bcd560c760d0b12e15bba8f81c86237cf.zip | |
Merge branches 'expcb.2026.07.24a', 'misc.2026.07.30a', 'rcu-tasks.2026.07.30a', 'srcu.2026.08.11a' and 'torture.2026.08.14a' into HEADgrafted
Changes:
Make expedited grace periods expedite normal RCU callbacks
Miscellaneous fixes:
* Improve diagnostic output with character task states.
* Mark accesses to inform KCSAN of concurrency design.
* Move from kmalloc() to kmalloc_obj().
* Documentation updates.
* Improve handling of RCU deferred quiescent states.
* Clean up unused function arguments and structure fields.
* Reduce show_rcu_gp_kthreads() stack space.
Tasks RCU updates:
* Clean up after SRCU re-implementation of Tasks Trace RCU.
* Mark accesses to inform KCSAN of concurrency design.
* Add ->lazy_timer status to diagnostic output.
* Remove an unnecessary memory barrier.
* Fix a data race, courtesy of KCSAN.
* Documentation updates.
* Convert cond_resched_tasks_rcu_qs() from macro to static inline
function.
SRCU updates:
* Add Rust helpers for SRCU.
* Avoid losing queued work at cleanup_srcu_struct() time.
Torture-test updates:
* Preparation work for immediate RCU priority deboosting.
* Test RCU readers from real interrupt handlers (as opposed to softirq).
* Simplify code through use of cpumask_next_wrap().
* Improve diagnostic output with character task states.
* Add rcutorture.nwriters parameter to allow lightweight stall testing,
and rcutorture.stall_only to make doing so easier.
* Test an RCU Tasks Trace grace period implying an RCU grace period.
* Make RCU Tasks Trace torturing track reader batches.
* Fix a data race, courtesy of KCSAN.
* Plug a shuffle_tmp_mask memory leak on kthread spawn failure.
Diffstat (limited to 'sound/soc/sof/sof-utils.c')
| -rw-r--r-- | sound/soc/sof/sof-utils.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/sound/soc/sof/sof-utils.c b/sound/soc/sof/sof-utils.c new file mode 100644 index 000000000..f70089317 --- /dev/null +++ b/sound/soc/sof/sof-utils.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2018-2022 Intel Corporation +// +// Author: Keyon Jie <yang.jie@linux.intel.com> +// + +#include <linux/unaligned.h> +#include <linux/io-64-nonatomic-lo-hi.h> +#include <linux/device.h> +#include <sound/memalloc.h> +#include <linux/module.h> +#include "sof-utils.h" + +/* + * Generic buffer page table creation. + * Take the each physical page address and drop the least significant unused + * bits from each (based on PAGE_SIZE). Then pack valid page address bits + * into compressed page table. + */ + +int snd_sof_create_page_table(struct device *dev, + struct snd_dma_buffer *dmab, + unsigned char *page_table, size_t size) +{ + int i, pages; + + pages = snd_sgbuf_aligned_pages(size); + + dev_dbg(dev, "generating page table for %p size 0x%zx pages %d\n", + dmab->area, size, pages); + + for (i = 0; i < pages; i++) { + /* + * The number of valid address bits for each page is 20. + * idx determines the byte position within page_table + * where the current page's address is stored + * in the compressed page_table. + * This can be calculated by multiplying the page number by 2.5. + */ + u32 idx = (5 * i) >> 1; + u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT; + u8 *pg_table; + + pg_table = (u8 *)(page_table + idx); + + /* + * pagetable compression: + * byte 0 byte 1 byte 2 byte 3 byte 4 byte 5 + * ___________pfn 0__________ __________pfn 1___________ _pfn 2... + * .... .... .... .... .... .... .... .... .... .... .... + * It is created by: + * 1. set current location to 0, PFN index i to 0 + * 2. put pfn[i] at current location in Little Endian byte order + * 3. calculate an intermediate value as + * x = (pfn[i+1] << 4) | (pfn[i] & 0xf) + * 4. put x at offset (current location + 2) in LE byte order + * 5. increment current location by 5 bytes, increment i by 2 + * 6. continue to (2) + */ + if (i & 1) + put_unaligned_le32((pg_table[0] & 0xf) | pfn << 4, + pg_table); + else + put_unaligned_le32(pfn, pg_table); + } + + return pages; +} +EXPORT_SYMBOL(snd_sof_create_page_table); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("SOF utils"); |
