Re: [PATCH v3 15/17] mm: pgtable: remove tlb_remove_page_ptdesc()
On Mon, Dec 23, 2024 at 05:41:01PM +0800, Qi Zheng wrote: > Here we are explicitly dealing with struct page, and the following logic > semms strange: > > tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); > > tlb_remove_page_ptdesc > --> tlb_remove_page(tlb, ptdesc_page(pt)); > > So remove tlb_remove_page_ptdesc() and make callers call tlb_remove_page() > directly. Please don't. The ptdesc wrappers are there as a part of reducing the size of struct page project [1]. For now struct ptdesc overlaps struct page, but the goal is to have them separate and always operate on struct ptdesc when working with page tables. [1] https://kernelnewbies.org/MatthewWilcox/Memdescs > Signed-off-by: Qi Zheng > Originally-by: Peter Zijlstra (Intel) > --- > arch/csky/include/asm/pgalloc.h | 2 +- > arch/hexagon/include/asm/pgalloc.h | 2 +- > arch/loongarch/include/asm/pgalloc.h | 2 +- > arch/m68k/include/asm/sun3_pgalloc.h | 2 +- > arch/mips/include/asm/pgalloc.h | 2 +- > arch/nios2/include/asm/pgalloc.h | 2 +- > arch/openrisc/include/asm/pgalloc.h | 2 +- > arch/riscv/include/asm/pgalloc.h | 2 +- > arch/sh/include/asm/pgalloc.h| 2 +- > arch/um/include/asm/pgalloc.h| 8 > include/asm-generic/tlb.h| 6 -- > 11 files changed, 13 insertions(+), 19 deletions(-) > > diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h > index f1ce5b7b28f22..936a43a49e704 100644 > --- a/arch/csky/include/asm/pgalloc.h > +++ b/arch/csky/include/asm/pgalloc.h > @@ -64,7 +64,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) > #define __pte_free_tlb(tlb, pte, address)\ > do { \ > pagetable_dtor(page_ptdesc(pte)); \ > - tlb_remove_page_ptdesc(tlb, page_ptdesc(pte)); \ > + tlb_remove_page(tlb, (pte));\ > } while (0) > > extern void pagetable_init(void); > diff --git a/arch/hexagon/include/asm/pgalloc.h > b/arch/hexagon/include/asm/pgalloc.h > index 40e42a0e71673..8b1550498f1bf 100644 > --- a/arch/hexagon/include/asm/pgalloc.h > +++ b/arch/hexagon/include/asm/pgalloc.h > @@ -90,7 +90,7 @@ static inline void pmd_populate_kernel(struct mm_struct > *mm, pmd_t *pmd, > #define __pte_free_tlb(tlb, pte, addr) \ > do { \ > pagetable_dtor((page_ptdesc(pte))); \ > - tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \ > + tlb_remove_page((tlb), (pte)); \ > } while (0) > > #endif > diff --git a/arch/loongarch/include/asm/pgalloc.h > b/arch/loongarch/include/asm/pgalloc.h > index 7211dff8c969e..5a4f22aeb6189 100644 > --- a/arch/loongarch/include/asm/pgalloc.h > +++ b/arch/loongarch/include/asm/pgalloc.h > @@ -58,7 +58,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct > *mm) > #define __pte_free_tlb(tlb, pte, address)\ > do { \ > pagetable_dtor(page_ptdesc(pte)); \ > - tlb_remove_page_ptdesc((tlb), page_ptdesc(pte));\ > + tlb_remove_page((tlb), (pte)); \ > } while (0) > > #ifndef __PAGETABLE_PMD_FOLDED > diff --git a/arch/m68k/include/asm/sun3_pgalloc.h > b/arch/m68k/include/asm/sun3_pgalloc.h > index 2b626cb3ad0ae..63d9f95f5e3dd 100644 > --- a/arch/m68k/include/asm/sun3_pgalloc.h > +++ b/arch/m68k/include/asm/sun3_pgalloc.h > @@ -20,7 +20,7 @@ extern const char bad_pmd_string[]; > #define __pte_free_tlb(tlb, pte, addr) \ > do { \ > pagetable_dtor(page_ptdesc(pte)); \ > - tlb_remove_page_ptdesc((tlb), page_ptdesc(pte));\ > + tlb_remove_page((tlb), (pte)); \ > } while (0) > > static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, > pte_t *pte) > diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h > index 36d9805033c4b..bbee21345154b 100644 > --- a/arch/mips/include/asm/pgalloc.h > +++ b/arch/mips/include/asm/pgalloc.h > @@ -57,7 +57,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t > *pgd) > #define __pte_free_tlb(tlb, pte, address)\ > do { \ > pagetable_dtor(page_ptdesc(pte)); \ > - tlb_remove_page_ptdesc((tlb), page_ptdesc(pte));\ > + tlb_remove_page((tlb), (pte)); \ > } while (0) > > #ifndef __PAGETABLE_PMD_FOLDED > diff --git a/arch/nios2/include/asm/pgalloc.h > b/arch/nios2/include/asm/pgalloc.h > index 12a536b7bfbd4..641cec8fb2a22 100644 > --- a/arch/nios2/include/asm/pgalloc.h > +++ b/arch/nios2/include/asm/pgalloc.h > @@ -31,7 +31,7 @@ extern pgd_t *pg
KVM: PPC: Book3E: KVM HV host module doesn't work anymore
Hi All, I found out which area is responsible for the KVM HV issue while reducing the revert patch. If I replace the following line in the file 'a/arch/powerpc/kvm/e500_mmu_host.c' then KVM HV works again. - pfn = __kvm_faultin_pfn(slot, gfn, FOLL_WRITE, NULL, &page); + pfn = gfn_to_pfn_memslot(slot, gfn); On 28/12/24 15:55, Paolo Bonzini wrote: > The fix is already found, I will send it out shortly but everybody is on > vacation now Thanks a lot! Could you please post the patch on this list? I would like to patch the RC5 of kernel 6.13 next week. Thanks, Christian -- Sent with BrassMonkey 33.4.0 (https://github.com/wicknix/brass-monkey/releases/tag/33.4.0)
Re: [PATCH v11 2/5] modpost: Produce extended MODVERSIONS information
On Tue, Dec 24, 2024 at 5:13 AM Matthew Maurer wrote: > > Generate both the existing modversions format and the new extended one > when running modpost. Presence of this metadata in the final .ko is > guarded by CONFIG_EXTENDED_MODVERSIONS. > > We no longer generate an error on long symbols in modpost if > CONFIG_EXTENDED_MODVERSIONS is set, as they can now be appropriately > encoded in the extended section. These symbols will be skipped in the > previous encoding. An error will still be generated if > CONFIG_EXTENDED_MODVERSIONS is not set. > > Reviewed-by: Sami Tolvanen > Signed-off-by: Matthew Maurer > --- > kernel/module/Kconfig| 10 > scripts/Makefile.modpost | 1 + > scripts/mod/modpost.c| 65 > +--- > 3 files changed, 72 insertions(+), 4 deletions(-) > > diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig > index > d443fc504ffca0d1001f880ec496ab1f21fe979e..9568b629a03ce8289d3f3597eefc66fc96445720 > 100644 > --- a/kernel/module/Kconfig > +++ b/kernel/module/Kconfig > @@ -207,6 +207,16 @@ config ASM_MODVERSIONS > assembly. This can be enabled only when the target architecture > supports it. > > +config EXTENDED_MODVERSIONS > + bool "Extended Module Versioning Support" > + depends on MODVERSIONS > + help > + This enables extended MODVERSIONs support, allowing long symbol > + names to be versioned. > + > + The most likely reason you would enable this is to enable Rust > + support. If unsure, say N. > + > config MODULE_SRCVERSION_ALL > bool "Source checksum for all modules" > help > diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost > index > ab0e94ea62496e11dbaa3ffc289ce546862795ca..40426fc6350985780c0092beb49c6cc29b9eff62 > 100644 > --- a/scripts/Makefile.modpost > +++ b/scripts/Makefile.modpost > @@ -43,6 +43,7 @@ MODPOST = $(objtree)/scripts/mod/modpost > modpost-args = > \ > $(if $(CONFIG_MODULES),-M) > \ > $(if $(CONFIG_MODVERSIONS),-m) > \ > + $(if $(CONFIG_EXTENDED_MODVERSIONS),-x) > \ > $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) > \ > $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) > \ > $(if $(KBUILD_MODPOST_WARN),-w) > \ > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c > index > fb787a5715f5e8b37713162979ca45355770dc73..c58f08681fc1e37929333ba3a3e0989c4db5a79d > 100644 > --- a/scripts/mod/modpost.c > +++ b/scripts/mod/modpost.c > @@ -33,6 +33,8 @@ static bool module_enabled; > static bool modversions; > /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ > static bool all_versions; > +/* Is CONFIG_EXTENDED_MODVERSIONS set? */ > +static bool extended_modversions; > /* If we are modposting external module set to 1 */ > static bool external_module; > /* Only warn about unresolved symbols */ > @@ -1804,6 +1806,52 @@ static void add_exported_symbols(struct buffer *buf, > struct module *mod) > } > } > > +/** > + * Record CRCs for unresolved symbols, supporting long names > + */ > +static void add_extended_versions(struct buffer *b, struct module *mod) > +{ > + struct symbol *s; > + > + if (!extended_modversions) > + return; > + > + buf_printf(b, "\n"); > + buf_printf(b, "static const s32 version_ext_crcs[]\n"); In general, 's32' (i.e. signed) and the '%x' printf-format (i.e. unsigned) are an odd combination. I know why you are mixing up these. Previously, we had a reason to use 's32' because the 'crc' field may contain a negative address offset. After commit 7b4537199a4a, there is no more reason for keeping this weirdness. I will apply the following first. https://lore.kernel.org/linux-kbuild/20241228154603.2234284-2-masahi...@kernel.org/T/#u Then, you can change 's32' to 'u32' in this series. > + buf_printf(b, "__used __section(\"__version_ext_crcs\") = {\n"); > + list_for_each_entry(s, &mod->unresolved_symbols, list) { > + if (!s->module) > + continue; > + if (!s->crc_valid) { > + /* > +* We already warned on this when producing the legacy > +* modversions table. > +*/ > + continue; Personally, I tend to avoid a noise change because you will change this comment to warn() in the next commit. It is up to you. > + } > + buf_printf(b, "\t%#8x,\n", s->crc); This is also a copy-paste of the existing code. I like to have zero-padding for better alignment. Please follow
[PATCH 05/14] cpumask: deprecate cpumask_next_wrap()
The next patche aligns implementation of cpumask_next_wrap() with the generic version in find.h which changes function signature. To make the transition smooth, this patch deprecates current implementation by adding an _old suffix. The following patches switch current users to the new implementation one by one. No functional changes were intended. Signed-off-by: Yury Norov --- arch/s390/kernel/processor.c| 2 +- drivers/nvme/host/tcp.c | 2 +- drivers/pci/controller/pci-hyperv.c | 2 +- drivers/scsi/lpfc/lpfc_init.c | 2 +- include/linux/cpumask.h | 4 ++-- kernel/padata.c | 2 +- lib/cpumask.c | 6 +++--- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 5ce9a795a0fe..42ca61909030 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -72,7 +72,7 @@ void notrace stop_machine_yield(const struct cpumask *cpumask) this_cpu = smp_processor_id(); if (__this_cpu_inc_return(cpu_relax_retry) >= spin_retry) { __this_cpu_write(cpu_relax_retry, 0); - cpu = cpumask_next_wrap(this_cpu, cpumask, this_cpu, false); + cpu = cpumask_next_wrap_old(this_cpu, cpumask, this_cpu, false); if (cpu >= nr_cpu_ids) return; if (arch_vcpu_is_preempted(cpu)) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 28c76a3e1bd2..054904376c3c 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1578,7 +1578,7 @@ static void nvme_tcp_set_queue_io_cpu(struct nvme_tcp_queue *queue) if (wq_unbound) queue->io_cpu = WORK_CPU_UNBOUND; else - queue->io_cpu = cpumask_next_wrap(n - 1, cpu_online_mask, -1, false); + queue->io_cpu = cpumask_next_wrap_old(n - 1, cpu_online_mask, -1, false); } static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index cdd5be16021d..86d1c2be8eb5 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -1757,7 +1757,7 @@ static int hv_compose_multi_msi_req_get_cpu(void) spin_lock_irqsave(&multi_msi_cpu_lock, flags); - cpu_next = cpumask_next_wrap(cpu_next, cpu_online_mask, nr_cpu_ids, + cpu_next = cpumask_next_wrap_old(cpu_next, cpu_online_mask, nr_cpu_ids, false); cpu = cpu_next; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7f57397d91a9..31622fb0614a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -12876,7 +12876,7 @@ lpfc_irq_rebalance(struct lpfc_hba *phba, unsigned int cpu, bool offline) if (offline) { /* Find next online CPU on original mask */ - cpu_next = cpumask_next_wrap(cpu, orig_mask, cpu, true); + cpu_next = cpumask_next_wrap_old(cpu, orig_mask, cpu, true); cpu_select = lpfc_next_online_cpu(orig_mask, cpu_next); /* Found a valid CPU */ diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 30042351f15f..b267a4f6a917 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -296,7 +296,7 @@ unsigned int cpumask_next_and(int n, const struct cpumask *src1p, #if NR_CPUS == 1 static __always_inline -unsigned int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap) +unsigned int cpumask_next_wrap_old(int n, const struct cpumask *mask, int start, bool wrap) { cpumask_check(start); if (n != -1) @@ -312,7 +312,7 @@ unsigned int cpumask_next_wrap(int n, const struct cpumask *mask, int start, boo return cpumask_first(mask); } #else -unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap); +unsigned int __pure cpumask_next_wrap_old(int n, const struct cpumask *mask, int start, bool wrap); #endif /** diff --git a/kernel/padata.c b/kernel/padata.c index d51bbc76b227..454ff2fca40b 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -274,7 +274,7 @@ static struct padata_priv *padata_find_next(struct parallel_data *pd, if (remove_object) { list_del_init(&padata->list); ++pd->processed; - pd->cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu, -1, false); + pd->cpu = cpumask_next_wrap_old(cpu, pd->cpumask.pcpu, -1, false); } spin_unlock(&reorder->lock); diff --git a/lib/cpumask.c b/lib/cpumask.c index e77ee9d46f71..c9a9b451772a 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -8,7 +8,7 @@ #include /** - * cpumask_next_wrap - helper to implement for_each_cpu_wrap + * cpumask_next_wrap_old - helper to implement for_each_cpu_wrap * @n: the cpu pri
[PATCH 06/14] cpumask: re-introduce cpumask_next{,_and}_wrap()
cpumask_next_wrap_old() has two additional parameters, comparing to it's analogue in linux/find.h find_next_bit_wrap(). The reason for that is historical. Before 4fe49b3b97c262 ("lib/bitmap: introduce for_each_set_bit_wrap() macro"), cpumask_next_wrap() was used to implement for_each_cpu_wrap() iterator. Now that the iterator is an alias to generic for_each_set_bit_wrap(), the additional parameters aren't used and may confuse readers. All existing users call cpumask_next_wrap() in a way that makes it possible to turn it to straight and simple alias to find_next_bit_wrap(). In a couple places kernel users opencode missing cpumask_next_and_wrap(). Add it as well. Signed-off-by: Yury Norov --- include/linux/cpumask.h | 37 + 1 file changed, 37 insertions(+) diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index b267a4f6a917..18c9908d50c4 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -284,6 +284,43 @@ unsigned int cpumask_next_and(int n, const struct cpumask *src1p, small_cpumask_bits, n + 1); } +/** + * cpumask_next_and_wrap - get the next cpu in *src1p & *src2p, starting from + *@n and wrapping around, if needed + * @n: the cpu prior to the place to search (i.e. return will be > @n) + * @src1p: the first cpumask pointer + * @src2p: the second cpumask pointer + * + * Return: >= nr_cpu_ids if no further cpus set in both. + */ +static __always_inline +unsigned int cpumask_next_and_wrap(int n, const struct cpumask *src1p, + const struct cpumask *src2p) +{ + /* -1 is a legal arg here. */ + if (n != -1) + cpumask_check(n); + return find_next_and_bit_wrap(cpumask_bits(src1p), cpumask_bits(src2p), + small_cpumask_bits, n + 1); +} + +/* + * cpumask_next_wrap - get the next cpu in *src, starting from + *@n and wrapping around, if needed + * @n: the cpu prior to the place to search + * @src: cpumask pointer + * + * Return: >= nr_cpu_ids if no further cpus set in both. + */ +static __always_inline +unsigned int cpumask_next_wrap(int n, const struct cpumask *src) +{ + /* -1 is a legal arg here. */ + if (n != -1) + cpumask_check(n); + return find_next_bit_wrap(cpumask_bits(src), small_cpumask_bits, n + 1); +} + /** * for_each_cpu - iterate over every cpu in a mask * @cpu: the (optionally unsigned) integer iterator -- 2.43.0
[PATCH 04/14] powerpc/xmon: simplify xmon_batch_next_cpu()
The function opencodes for_each_cpu_wrap() macro. As a loop termination condition it uses cpumask_empty(), which is O(N), and it makes the whole algorithm O(N^2). Switching to for_each_cpu_wrap() simplifies the logic, and makes the algorithm linear. Signed-off-by: Yury Norov --- arch/powerpc/xmon/xmon.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index f4e841a36458..d7809f15dc68 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1271,11 +1271,7 @@ static int xmon_batch_next_cpu(void) { unsigned long cpu; - while (!cpumask_empty(&xmon_batch_cpus)) { - cpu = cpumask_next_wrap(smp_processor_id(), &xmon_batch_cpus, - xmon_batch_start_cpu, true); - if (cpu >= nr_cpu_ids) - break; + for_each_cpu_wrap(cpu, &xmon_batch_cpus, xmon_batch_start_cpu) { if (xmon_batch_start_cpu == -1) xmon_batch_start_cpu = cpu; if (xmon_switch_cpu(cpu)) -- 2.43.0
[PATCH 00/14] cpumask: cleanup cpumask_next_wrap() implementation and usage
cpumask_next_wrap() is overly complicated, comparing to it's generic version find_next_bit_wrap(), not mentioning it duplicates the above. It roots to the times when the function was used in the implementation of for_each_cpu_wrap() iterator. The function has 2 additional parameters that were used to catch loop termination condition for the iterator. (Although, only one is needed.) Since 4fe49b3b97c262 ("lib/bitmap: introduce for_each_set_bit_wrap() macro"), for_each_cpu_wrap() is wired to corresponding generic wrapping bitmap iterator, and additional complexity of cpumask_next_wrap() is not needed anymore. All existing users call cpumask_next_wrap() in a manner that makes it possible to turn it to a straight and simple alias to find_next_bit_wrap(). This series replaces historical 4-parameter cpumask_next_wrap() with a thin 2-parameter wrapper around find_next_bit_wrap(). Where it's possible to use for_each_cpu_wrap() iterator, the code is switched to use it because it's always preferable to use iterators over open loops. This series touches various scattered subsystems and To-list for the whole series is quite a long. To minimize noise, I send cover-letter and key patches #5 and 6 to every person involved. All other patches are sent individually to those pointed by scripts/get_maintainers.pl. I'd like to move the series with my bitmap-for-next branch as a whole. Yury Norov (14): objpool: rework objpool_pop() virtio_net: simplify virtnet_set_affinity() ibmvnic: simplify ibmvnic_set_queue_affinity() powerpc/xmon: simplify xmon_batch_next_cpu() cpumask: deprecate cpumask_next_wrap() cpumask: re-introduce cpumask_next_wrap() cpumask: use cpumask_next_wrap() where appropriate padata: switch padata_find_next() to using cpumask_next_wrap() s390: switch stop_machine_yield() to using cpumask_next_wrap() nvme-tcp: switch nvme_tcp_set_queue_io_cpu() to using cpumask_next_wrap() scsi: lpfc: switch lpfc_irq_rebalance() to using cpumask_next_wrap() scsi: lpfc: rework lpfc_next_{online,present}_cpu() PCI: hv: switch hv_compose_multi_msi_req_get_cpu() to using cpumask_next_wrap() cpumask: drop cpumask_next_wrap_old() arch/powerpc/xmon/xmon.c| 6 +--- arch/s390/kernel/processor.c| 2 +- drivers/net/ethernet/ibm/ibmvnic.c | 17 +- drivers/net/virtio_net.c| 12 +--- drivers/nvme/host/tcp.c | 2 +- drivers/pci/controller/pci-hyperv.c | 3 +- drivers/scsi/lpfc/lpfc.h| 23 +++--- drivers/scsi/lpfc/lpfc_init.c | 2 +- include/linux/cpumask.h | 48 - include/linux/objpool.h | 7 ++--- kernel/padata.c | 2 +- lib/cpumask.c | 37 ++ 12 files changed, 60 insertions(+), 101 deletions(-) -- 2.43.0
[PATCH 03/14] ibmvnic: simplify ibmvnic_set_queue_affinity()
A loop based on cpumask_next_wrap() opencodes the dedicated macro for_each_online_cpu_wrap(). Using the macro allows to avoid setting bits affinity mask more than once when stride >= num_online_cpus. This also helps to drop cpumask handling code in the caller function. Signed-off-by: Yury Norov --- drivers/net/ethernet/ibm/ibmvnic.c | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index e95ae0d39948..4cfd90fb206b 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -234,11 +234,16 @@ static int ibmvnic_set_queue_affinity(struct ibmvnic_sub_crq_queue *queue, (*stragglers)--; } /* atomic write is safer than writing bit by bit directly */ - for (i = 0; i < stride; i++) { - cpumask_set_cpu(*cpu, mask); - *cpu = cpumask_next_wrap(*cpu, cpu_online_mask, -nr_cpu_ids, false); + for_each_online_cpu_wrap(i, *cpu) { + if (!stride--) + break; + cpumask_set_cpu(i, mask); } + + /* For the next queue we start from the first unused CPU in this queue */ + if (i < nr_cpu_ids) + *cpu = i + 1; + /* set queue affinity mask */ cpumask_copy(queue->affinity_mask, mask); rc = irq_set_affinity_and_hint(queue->irq, queue->affinity_mask); @@ -256,7 +261,7 @@ static void ibmvnic_set_affinity(struct ibmvnic_adapter *adapter) int num_rxqs = adapter->num_active_rx_scrqs, i_rxqs = 0; int num_txqs = adapter->num_active_tx_scrqs, i_txqs = 0; int total_queues, stride, stragglers, i; - unsigned int num_cpu, cpu; + unsigned int num_cpu, cpu = 0; bool is_rx_queue; int rc = 0; @@ -274,8 +279,6 @@ static void ibmvnic_set_affinity(struct ibmvnic_adapter *adapter) stride = max_t(int, num_cpu / total_queues, 1); /* number of leftover cpu's */ stragglers = num_cpu >= total_queues ? num_cpu % total_queues : 0; - /* next available cpu to assign irq to */ - cpu = cpumask_next(-1, cpu_online_mask); for (i = 0; i < total_queues; i++) { is_rx_queue = false; -- 2.43.0
[PATCH v2 0/3] sysfs: constify bin_attribute argument of sysfs_bin_attr_simple_read()
Most users use this function through the BIN_ATTR_SIMPLE* macros, they can handle the switch transparently. This series is meant to be merged through the driver core tree. Signed-off-by: Thomas Weißschuh --- Changes in v2: - Rebase on torvalds/master - Drop wmi-bmof patch - Pick up Acks from Andrii - Link to v1: https://lore.kernel.org/r/20241205-sysfs-const-bin_attr-simple-v1-0-4a4e4ced7...@weissschuh.net --- Thomas Weißschuh (3): sysfs: constify bin_attribute argument of sysfs_bin_attr_simple_read() btf: Switch vmlinux BTF attribute to sysfs_bin_attr_simple_read() btf: Switch module BTF attribute to sysfs_bin_attr_simple_read() arch/powerpc/platforms/powernv/opal.c | 2 +- fs/sysfs/file.c | 2 +- include/linux/sysfs.h | 4 ++-- kernel/bpf/btf.c | 15 ++- kernel/bpf/sysfs_btf.c| 12 ++-- kernel/module/sysfs.c | 2 +- 6 files changed, 9 insertions(+), 28 deletions(-) --- base-commit: d6ef8b40d075c425f548002d2f35ae3f06e9cf96 change-id: 20241122-sysfs-const-bin_attr-simple-7c0ddb2fcf12 Best regards, -- Thomas Weißschuh
[PATCH v2 1/3] sysfs: constify bin_attribute argument of sysfs_bin_attr_simple_read()
Most users use this function through the BIN_ATTR_SIMPLE* macros, they can handle the switch transparently. Also adapt the two non-macro users in the same change. Signed-off-by: Thomas Weißschuh --- arch/powerpc/platforms/powernv/opal.c | 2 +- fs/sysfs/file.c | 2 +- include/linux/sysfs.h | 4 ++-- kernel/module/sysfs.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 5d0f35bb917ebced8c741cd3af2c511949a1d2ef..013637e2b2a8e6a4ec6b93a520f8d5d9d3245467 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -818,7 +818,7 @@ static int opal_add_one_export(struct kobject *parent, const char *export_name, sysfs_bin_attr_init(attr); attr->attr.name = name; attr->attr.mode = 0400; - attr->read = sysfs_bin_attr_simple_read; + attr->read_new = sysfs_bin_attr_simple_read; attr->private = __va(vals[0]); attr->size = vals[1]; diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 785408861c01c89fc84c787848243a13c1338367..6931308876c4ac3b4c19878d5e1158ad8fe4f16f 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -817,7 +817,7 @@ EXPORT_SYMBOL_GPL(sysfs_emit_at); * Returns number of bytes written to @buf. */ ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj, - struct bin_attribute *attr, char *buf, + const struct bin_attribute *attr, char *buf, loff_t off, size_t count) { memcpy(buf, attr->private + off, count); diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 0f2fcd244523f050c5286f19d4fe1846506f9214..2205561159afdb57d0a250bb0439b28c01d9010e 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -511,7 +511,7 @@ __printf(3, 4) int sysfs_emit_at(char *buf, int at, const char *fmt, ...); ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj, - struct bin_attribute *attr, char *buf, + const struct bin_attribute *attr, char *buf, loff_t off, size_t count); #else /* CONFIG_SYSFS */ @@ -774,7 +774,7 @@ static inline int sysfs_emit_at(char *buf, int at, const char *fmt, ...) static inline ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj, -struct bin_attribute *attr, +const struct bin_attribute *attr, char *buf, loff_t off, size_t count) { diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 456358e1fdc43e6b5b24f383bbefa37812971174..254017b58b645d4afcf6876d29bcc2e2113a8dc4 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -196,7 +196,7 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) nattr->attr.mode = 0444; nattr->size = info->sechdrs[i].sh_size; nattr->private = (void *)info->sechdrs[i].sh_addr; - nattr->read = sysfs_bin_attr_simple_read; + nattr->read_new = sysfs_bin_attr_simple_read; ++nattr; } ++loaded; -- 2.47.1
[PATCH v2 3/3] btf: Switch module BTF attribute to sysfs_bin_attr_simple_read()
The generic function from the sysfs core can replace the custom one. Signed-off-by: Thomas Weißschuh Acked-by: Andrii Nakryiko --- kernel/bpf/btf.c | 15 ++- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index e5a5f023cedd5c288c2774218862c69db469917f..76de36d2552002d1e25c826d701340d9cde07ba1 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -8011,17 +8011,6 @@ struct btf_module { static LIST_HEAD(btf_modules); static DEFINE_MUTEX(btf_module_mutex); -static ssize_t -btf_module_read(struct file *file, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t len) -{ - const struct btf *btf = bin_attr->private; - - memcpy(buf, btf->data + off, len); - return len; -} - static void purge_cand_cache(struct btf *btf); static int btf_module_notify(struct notifier_block *nb, unsigned long op, @@ -8082,8 +8071,8 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, attr->attr.name = btf->name; attr->attr.mode = 0444; attr->size = btf->data_size; - attr->private = btf; - attr->read = btf_module_read; + attr->private = btf->data; + attr->read_new = sysfs_bin_attr_simple_read; err = sysfs_create_bin_file(btf_kobj, attr); if (err) { -- 2.47.1
[PATCH v2 2/3] btf: Switch vmlinux BTF attribute to sysfs_bin_attr_simple_read()
The generic function from the sysfs core can replace the custom one. Signed-off-by: Thomas Weißschuh Acked-by: Andrii Nakryiko --- This is a replacement for [0], as Alexei was not happy about BIN_ATTR_SIMPLE_RO() [0] https://lore.kernel.org/lkml/20241122-sysfs-const-bin_attr-bpf-v1-1-823aea399...@weissschuh.net/ --- kernel/bpf/sysfs_btf.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/kernel/bpf/sysfs_btf.c b/kernel/bpf/sysfs_btf.c index fedb54c94cdb830a4890d33677dcc5a6e236c13f..81d6cf90584a7157929c50f62a5c6862e7a3d081 100644 --- a/kernel/bpf/sysfs_btf.c +++ b/kernel/bpf/sysfs_btf.c @@ -12,24 +12,16 @@ extern char __start_BTF[]; extern char __stop_BTF[]; -static ssize_t -btf_vmlinux_read(struct file *file, struct kobject *kobj, -struct bin_attribute *bin_attr, -char *buf, loff_t off, size_t len) -{ - memcpy(buf, __start_BTF + off, len); - return len; -} - static struct bin_attribute bin_attr_btf_vmlinux __ro_after_init = { .attr = { .name = "vmlinux", .mode = 0444, }, - .read = btf_vmlinux_read, + .read_new = sysfs_bin_attr_simple_read, }; struct kobject *btf_kobj; static int __init btf_vmlinux_init(void) { + bin_attr_btf_vmlinux.private = __start_BTF; bin_attr_btf_vmlinux.size = __stop_BTF - __start_BTF; if (bin_attr_btf_vmlinux.size == 0) -- 2.47.1