diff --git a/MAINTAINERS b/MAINTAINERS index 0b64b5ac1828..64dc2a2869ab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4614,6 +4614,7 @@ F: lib/bitmap.c F: lib/cpumask.c F: lib/find_bit.c F: lib/find_bit_benchmark.c +F: lib/region_alloc_benchmark.c F: lib/test_bitmap.c F: lib/tests/cpumask_kunit.c F: tools/include/linux/bitfield.h @@ -15608,6 +15609,7 @@ F: Documentation/core-api/maple_tree.rst F: include/linux/maple_tree.h F: include/trace/events/maple_tree.h F: lib/maple_tree.c +F: lib/region_alloc_benchmark.c F: lib/test_maple_tree.c F: rust/helpers/maple_tree.c F: rust/kernel/maple_tree.rs @@ -29448,6 +29450,7 @@ F: Documentation/core-api/xarray.rst F: include/linux/idr.h F: include/linux/xarray.h F: lib/idr.c +F: lib/region_alloc_benchmark.c F: lib/test_xarray.c F: lib/xarray.c F: tools/testing/radix-tree diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index b71467c48b87..f6d993b9b1d4 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -127,7 +127,7 @@ static ssize_t mmdc_pmu_cpumask_show(struct device *dev, { struct mmdc_pmu *pmu_mmdc = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu_mmdc->cpu)); } static struct device_attribute mmdc_pmu_cpumask_attr = diff --git a/arch/arm/mm/cache-l2x0-pmu.c b/arch/arm/mm/cache-l2x0-pmu.c index 3d9caf7464bf..478227078837 100644 --- a/arch/arm/mm/cache-l2x0-pmu.c +++ b/arch/arm/mm/cache-l2x0-pmu.c @@ -390,7 +390,7 @@ static struct attribute_group l2x0_pmu_event_attrs_group = { static ssize_t l2x0_pmu_cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { - return cpumap_print_to_pagebuf(true, buf, &pmu_cpu); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu_cpu)); } static struct device_attribute l2x0_pmu_cpumask_attr = diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f9bc53b60f99..7761099dde9e 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -773,7 +773,7 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping, start = bitmap_find_next_zero_area(mapping->bitmaps[i], mapping->bits, 0, count, align); - if (start > mapping->bits) + if (start >= mapping->bits) continue; bitmap_set(mapping->bitmaps[i], start, count); @@ -794,7 +794,7 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping, start = bitmap_find_next_zero_area(mapping->bitmaps[i], mapping->bits, 0, count, align); - if (start > mapping->bits) { + if (start >= mapping->bits) { spin_unlock_irqrestore(&mapping->lock, flags); return DMA_MAPPING_ERROR; } diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 04e5ea38bdc0..cb0933061006 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -690,7 +690,8 @@ show_shared_cpumap(struct kobject *k, struct kobj_attribute *attr, char *buf, bo mask = &cache->shared_cpu_map; - return cpumap_print_to_pagebuf(list, buf, mask); + return sysfs_emit(buf, list ? "%*pbl\n" : "%*pb\n", + cpumask_pr_args(mask)); } static ssize_t shared_cpu_map_show(struct kobject *k, struct kobj_attribute *attr, char *buf) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index abb4cfb11fcc..b0eedf185960 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -429,7 +429,7 @@ static char *memdup_to_str(char *maybe_str, int max_len, gfp_t gfp) static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { - return cpumap_print_to_pagebuf(true, buf, &hv_24x7_cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&hv_24x7_cpumask)); } static ssize_t sockets_show(struct device *dev, diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 7269273d3aa8..76495744f52a 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -100,7 +100,7 @@ static ssize_t kernel_version_show(struct device *dev, static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { - return cpumap_print_to_pagebuf(true, buf, &hv_gpci_cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&hv_gpci_cpumask)); } /* Interface attribute array index to store system information */ diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 1d2db6d3e226..f401181d8669 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -117,7 +117,7 @@ static ssize_t imc_pmu_cpumask_get_attr(struct device *dev, return 0; } - return cpumap_print_to_pagebuf(true, buf, active_mask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(active_mask)); } static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL); diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c index 456a4f64ae0a..2f38d4b41ad3 100644 --- a/arch/powerpc/sysdev/msi_bitmap.c +++ b/arch/powerpc/sysdev/msi_bitmap.c @@ -21,7 +21,7 @@ int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num) offset = bitmap_find_next_zero_area(bmp->bitmap, bmp->irq_count, 0, num, (1 << order) - 1); - if (offset > bmp->irq_count) + if (offset >= bmp->irq_count) goto err; bitmap_set(bmp->bitmap, offset, num); diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index 07b110e8418a..f332c7089bd5 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -137,7 +137,7 @@ static ssize_t _iommu_cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { - return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&iommu_cpumask)); } static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL); diff --git a/arch/x86/events/amd/power.c b/arch/x86/events/amd/power.c index 744dffa42dee..66197214b010 100644 --- a/arch/x86/events/amd/power.c +++ b/arch/x86/events/amd/power.c @@ -150,7 +150,7 @@ static void pmu_event_read(struct perf_event *event) static ssize_t get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf) { - return cpumap_print_to_pagebuf(true, buf, &cpu_mask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&cpu_mask)); } static DEVICE_ATTR(cpumask, S_IRUGO, get_attr_cpumask, NULL); diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index 222dfab9225f..7181973b5b12 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -353,7 +353,7 @@ static ssize_t amd_uncore_attr_show_cpumask(struct device *dev, struct pmu *ptr = dev_get_drvdata(dev); struct amd_uncore_pmu *pmu = container_of(ptr, struct amd_uncore_pmu, pmu); - return cpumap_print_to_pagebuf(true, buf, &pmu->active_mask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu->active_mask)); } static DEVICE_ATTR(cpumask, S_IRUGO, amd_uncore_attr_show_cpumask, NULL); diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 27cda71c96ce..cc13164d948f 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -7590,7 +7590,7 @@ static ssize_t intel_hybrid_get_attr_cpus(struct device *dev, struct x86_hybrid_pmu *pmu = container_of(dev_get_drvdata(dev), struct x86_hybrid_pmu, pmu); - return cpumap_print_to_pagebuf(true, buf, &pmu->supported_cpus); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu->supported_cpus)); } static DEVICE_ATTR(cpus, S_IRUGO, intel_hybrid_get_attr_cpus, NULL); diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 9f8a80c9dcb6..b2109b37ea7f 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -861,7 +861,7 @@ static ssize_t uncore_get_attr_cpumask(struct device *dev, { struct intel_uncore_pmu *pmu = container_of(dev_get_drvdata(dev), struct intel_uncore_pmu, pmu); - return cpumap_print_to_pagebuf(true, buf, &pmu->cpu_mask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu->cpu_mask)); } static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 19d288a3c80c..69e52fed4241 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -218,7 +218,7 @@ static ssize_t show_cpus_attr(struct device *dev, { struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr); - return cpumap_print_to_pagebuf(true, buf, ca->map); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(ca->map)); } #define _CPU_ATTR(name, map) \ diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index fe69053b2394..60a133e23e5f 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -28,7 +28,7 @@ static u32 ccp_alloc_ksb(struct ccp_cmd_queue *cmd_q, unsigned int count) ccp->sb_count, ccp->sb_start, count, 0); - if (start <= ccp->sb_count) { + if (start < ccp->sb_count) { bitmap_set(ccp->sb, start, count); mutex_unlock(&ccp->sb_mutex); diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 7b73332d6aa1..dcd6aab51e47 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -47,7 +47,7 @@ static u32 ccp_lsb_alloc(struct ccp_cmd_queue *cmd_q, unsigned int count) MAX_LSB_CNT * LSB_SIZE, 0, count, 0); - if (start <= MAX_LSB_CNT * LSB_SIZE) { + if (start < MAX_LSB_CNT * LSB_SIZE) { bitmap_set(ccp->lsbmap, start, count); mutex_unlock(&ccp->sb_mutex); diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c index 5e6e7e900bda..255aee1bdd91 100644 --- a/drivers/devfreq/event/rockchip-dfi.c +++ b/drivers/devfreq/event/rockchip-dfi.c @@ -354,7 +354,7 @@ static ssize_t ddr_perf_cpumask_show(struct device *dev, struct pmu *pmu = dev_get_drvdata(dev); struct rockchip_dfi *dfi = container_of(pmu, struct rockchip_dfi, pmu); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(dfi->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(dfi->cpu))); } static struct device_attribute ddr_perf_cpumask_attr = diff --git a/drivers/devfreq/hisi_uncore_freq.c b/drivers/devfreq/hisi_uncore_freq.c index bef718d6ae35..e1f64b723082 100644 --- a/drivers/devfreq/hisi_uncore_freq.c +++ b/drivers/devfreq/hisi_uncore_freq.c @@ -540,7 +540,7 @@ static ssize_t related_cpus_show(struct device *dev, { struct hisi_uncore_freq *uncore = dev_get_drvdata(dev->parent); - return cpumap_print_to_pagebuf(true, buf, &uncore->related_cpus); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&uncore->related_cpus)); } static DEVICE_ATTR_RO(related_cpus); diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c index e67ba9891082..e045e92cd898 100644 --- a/drivers/firmware/psci/psci_checker.c +++ b/drivers/firmware/psci/psci_checker.c @@ -186,7 +186,6 @@ static int hotplug_tests(void) { int i, nb_cpu_group, err = -ENOMEM; cpumask_var_t offlined_cpus, *cpu_groups; - char *page_buf; if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL)) return err; @@ -194,10 +193,6 @@ static int hotplug_tests(void) nb_cpu_group = alloc_init_cpu_groups(&cpu_groups); if (nb_cpu_group < 0) goto out_free_cpus; - page_buf = (char *)__get_free_page(GFP_KERNEL); - if (!page_buf) - goto out_free_cpu_groups; - /* * Of course the last CPU cannot be powered down and cpu_down() should * refuse doing that. @@ -210,17 +205,11 @@ static int hotplug_tests(void) * off, the cpu group itself should shut down. */ for (i = 0; i < nb_cpu_group; ++i) { - ssize_t len = cpumap_print_to_pagebuf(true, page_buf, - cpu_groups[i]); - /* Remove trailing newline. */ - page_buf[len - 1] = '\0'; - pr_info("Trying to turn off and on again group %d (CPUs %s)\n", - i, page_buf); + pr_info("Trying to turn off and on again group %d (CPUs %*pbl)\n", + i, cpumask_pr_args(cpu_groups[i])); err += down_and_up_cpus(cpu_groups[i], offlined_cpus); } - free_page((unsigned long)page_buf); -out_free_cpu_groups: free_cpu_groups(nb_cpu_group, &cpu_groups); out_free_cpus: free_cpumask_var(offlined_cpus); diff --git a/drivers/fpga/dfl-fme-perf.c b/drivers/fpga/dfl-fme-perf.c index 7422d2bc6f37..7aa4983ab67d 100644 --- a/drivers/fpga/dfl-fme-perf.c +++ b/drivers/fpga/dfl-fme-perf.c @@ -183,7 +183,7 @@ static ssize_t cpumask_show(struct device *dev, priv = to_fme_perf_priv(pmu); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(priv->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(priv->cpu))); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c index 94c371c49135..233c4c32513c 100644 --- a/drivers/hwtracing/ptt/hisi_ptt.c +++ b/drivers/hwtracing/ptt/hisi_ptt.c @@ -780,7 +780,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev)); const cpumask_t *cpumask = cpumask_of_node(dev_to_node(&hisi_ptt->pdev->dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask)); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index cfd9dd0f7e81..f253c8ee182d 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "hfi.h" #include "common.h" @@ -1049,7 +1050,7 @@ ssize_t sdma_get_cpu_to_sde_map(struct sdma_engine *sde, char *buf) if (cpumask_empty(&sde->cpu_mask)) snprintf(buf, PAGE_SIZE, "%s\n", "empty"); else - cpumap_print_to_pagebuf(true, buf, &sde->cpu_mask); + sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&sde->cpu_mask)); mutex_unlock(&process_to_sde_mutex); return strnlen(buf, PAGE_SIZE); } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c index 5ba791fa3676..b25ad2a37196 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c @@ -43,7 +43,7 @@ int s5p_mfc_alloc_priv_buf(struct s5p_mfc_dev *dev, unsigned int mem_ctx, if (dev->mem_virt) { start = bitmap_find_next_zero_area(dev->mem_bitmap, bits, 0, count, align); - if (start > bits) + if (start >= bits) goto no_mem; bitmap_set(dev->mem_bitmap, start, count); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 5ec0b245a69b..d6083552b287 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -112,7 +112,8 @@ static ssize_t pci_dev_show_local_cpu(struct device *dev, bool list, #else mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); #endif - return cpumap_print_to_pagebuf(list, buf, mask); + return sysfs_emit(buf, list ? "%*pbl\n" : "%*pb\n", + cpumask_pr_args(mask)); } static ssize_t local_cpus_show(struct device *dev, @@ -137,7 +138,7 @@ static ssize_t cpuaffinity_show(struct device *dev, { const struct cpumask *cpumask = cpumask_of_pcibus(to_pci_bus(dev)); - return cpumap_print_to_pagebuf(false, buf, cpumask); + return sysfs_emit(buf, "%*pb\n", cpumask_pr_args(cpumask)); } static DEVICE_ATTR_RO(cpuaffinity); @@ -146,7 +147,7 @@ static ssize_t cpulistaffinity_show(struct device *dev, { const struct cpumask *cpumask = cpumask_of_pcibus(to_pci_bus(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask)); } static DEVICE_ATTR_RO(cpulistaffinity); diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c index de77da83df2e..fc934bccf4a6 100644 --- a/drivers/perf/alibaba_uncore_drw_pmu.c +++ b/drivers/perf/alibaba_uncore_drw_pmu.c @@ -221,7 +221,7 @@ static ssize_t ali_drw_pmu_cpumask_show(struct device *dev, { struct ali_drw_pmu *drw_pmu = to_ali_drw_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(drw_pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(drw_pmu->cpu))); } static struct device_attribute ali_drw_pmu_cpumask_attr = diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c index c1e755c356a3..f614aa3434a5 100644 --- a/drivers/perf/amlogic/meson_ddr_pmu_core.c +++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c @@ -191,7 +191,7 @@ static ssize_t meson_ddr_perf_cpumask_show(struct device *dev, { struct ddr_pmu *pmu = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu))); } static struct device_attribute meson_ddr_perf_cpumask_attr = diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c index 1cc3214d6b6d..f0ef0a679e74 100644 --- a/drivers/perf/arm-cci.c +++ b/drivers/perf/arm-cci.c @@ -1351,7 +1351,7 @@ static ssize_t pmu_cpumask_attr_show(struct device *dev, struct pmu *pmu = dev_get_drvdata(dev); struct cci_pmu *cci_pmu = to_cci_pmu(pmu); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(cci_pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(cci_pmu->cpu))); } static struct device_attribute pmu_cpumask_attr = diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c index c18a0e3205ab..c40da3450c8f 100644 --- a/drivers/perf/arm-ccn.c +++ b/drivers/perf/arm-ccn.c @@ -537,7 +537,7 @@ static ssize_t arm_ccn_pmu_cpumask_show(struct device *dev, { struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(ccn->dt.cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(ccn->dt.cpu))); } static struct device_attribute arm_ccn_pmu_cpumask_attr = diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index a03e2a8ca41e..b162de3d9d16 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -1516,7 +1516,7 @@ static ssize_t arm_cmn_cpumask_show(struct device *dev, { struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(cmn->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(cmn->cpu))); } static struct device_attribute arm_cmn_cpumask_attr = diff --git a/drivers/perf/arm-ni.c b/drivers/perf/arm-ni.c index 66858c65215d..03a1c6bf9223 100644 --- a/drivers/perf/arm-ni.c +++ b/drivers/perf/arm-ni.c @@ -239,7 +239,7 @@ static ssize_t arm_ni_cpumask_show(struct device *dev, { struct arm_ni *ni = cd_to_ni(pmu_to_cd(dev_get_drvdata(dev))); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(ni->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(ni->cpu))); } static struct device_attribute arm_ni_cpumask_attr = diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c index 60005f89892d..912f03ce3ef5 100644 --- a/drivers/perf/arm_cspmu/arm_cspmu.c +++ b/drivers/perf/arm_cspmu/arm_cspmu.c @@ -337,7 +337,7 @@ static ssize_t arm_cspmu_cpumask_show(struct device *dev, default: return 0; } - return cpumap_print_to_pagebuf(true, buf, cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask)); } static struct attribute *arm_cspmu_cpumask_attrs[] = { diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c index 4f6b196160f8..467147a05eec 100644 --- a/drivers/perf/arm_dmc620_pmu.c +++ b/drivers/perf/arm_dmc620_pmu.c @@ -237,8 +237,8 @@ static ssize_t dmc620_pmu_cpumask_show(struct device *dev, { struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, - cpumask_of(dmc620_pmu->irq->cpu)); + return sysfs_emit(buf, "%*pbl\n", + cpumask_pr_args(cpumask_of(dmc620_pmu->irq->cpu))); } static struct device_attribute dmc620_pmu_cpumask_attr = diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c index 32b0dd7c693b..bcbd19e075a5 100644 --- a/drivers/perf/arm_dsu_pmu.c +++ b/drivers/perf/arm_dsu_pmu.c @@ -157,7 +157,7 @@ static ssize_t dsu_pmu_cpumask_show(struct device *dev, default: return 0; } - return cpumap_print_to_pagebuf(true, buf, cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask)); } static struct attribute *dsu_pmu_format_attrs[] = { diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index aa1dac0b440f..115069565389 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -570,7 +570,7 @@ static ssize_t cpus_show(struct device *dev, struct device_attribute *attr, char *buf) { struct arm_pmu *armpmu = to_arm_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, &armpmu->supported_cpus); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&armpmu->supported_cpus)); } static DEVICE_ATTR_RO(cpus); diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c index 621f02a7f43b..8ce34e6bb82b 100644 --- a/drivers/perf/arm_smmuv3_pmu.c +++ b/drivers/perf/arm_smmuv3_pmu.c @@ -537,7 +537,7 @@ static ssize_t smmu_pmu_cpumask_show(struct device *dev, { struct smmu_pmu *smmu_pmu = to_smmu_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(smmu_pmu->on_cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(smmu_pmu->on_cpu))); } static struct device_attribute smmu_pmu_cpumask_attr = diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index b64cf2313a20..b70f3fedf028 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -343,7 +343,7 @@ static ssize_t cpumask_show(struct device *dev, { struct arm_spe_pmu *spe_pmu = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, &spe_pmu->supported_cpus); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&spe_pmu->supported_cpus)); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c index bb32cd1084e9..2c8a03cc11e4 100644 --- a/drivers/perf/cxl_pmu.c +++ b/drivers/perf/cxl_pmu.c @@ -568,7 +568,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, { struct cxl_pmu_info *info = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(info->on_cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(info->on_cpu))); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c index f5f3e5b83f5b..6b9ed59de26e 100644 --- a/drivers/perf/dwc_pcie_pmu.c +++ b/drivers/perf/dwc_pcie_pmu.c @@ -121,7 +121,7 @@ static ssize_t cpumask_show(struct device *dev, { struct dwc_pcie_pmu *pcie_pmu = to_dwc_pcie_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pcie_pmu->on_cpu))); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c index 6d1e99abf110..dd8046265584 100644 --- a/drivers/perf/fsl_imx8_ddr_perf.c +++ b/drivers/perf/fsl_imx8_ddr_perf.c @@ -237,7 +237,7 @@ static ssize_t ddr_perf_cpumask_show(struct device *dev, { struct ddr_pmu *pmu = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu))); } static struct device_attribute ddr_perf_cpumask_attr = diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c index 9dbc3187ef52..d59bc5ea3155 100644 --- a/drivers/perf/fsl_imx9_ddr_perf.c +++ b/drivers/perf/fsl_imx9_ddr_perf.c @@ -159,7 +159,7 @@ static ssize_t ddr_perf_cpumask_show(struct device *dev, { struct ddr_pmu *pmu = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu))); } static struct device_attribute ddr_perf_cpumask_attr = diff --git a/drivers/perf/fujitsu_uncore_pmu.c b/drivers/perf/fujitsu_uncore_pmu.c index 8c87d91e64b5..fa64146fcac6 100644 --- a/drivers/perf/fujitsu_uncore_pmu.c +++ b/drivers/perf/fujitsu_uncore_pmu.c @@ -373,7 +373,7 @@ static ssize_t cpumask_show(struct device *dev, { struct uncore_pmu *uncorepmu = to_uncore_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(uncorepmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(uncorepmu->cpu))); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c index c5394d007b61..0f55d871c67e 100644 --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c @@ -121,7 +121,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, c { struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pcie_pmu->on_cpu))); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c index f6f5b4470efe..77390d033d08 100644 --- a/drivers/perf/hisilicon/hisi_uncore_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c @@ -56,7 +56,7 @@ static ssize_t hisi_associated_cpus_sysfs_show(struct device *dev, { struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, &hisi_pmu->associated_cpus); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&hisi_pmu->associated_cpus)); } static DEVICE_ATTR(associated_cpus, 0444, hisi_associated_cpus_sysfs_show, NULL); diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c index 9c82bf4ee2c4..0a8cb6166408 100644 --- a/drivers/perf/marvell_cn10k_ddr_pmu.c +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c @@ -471,7 +471,7 @@ static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev, { struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu))); } static struct device_attribute cn10k_ddr_perf_cpumask_attr = diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c index 51ccb0befa05..54909d0031b7 100644 --- a/drivers/perf/marvell_cn10k_tad_pmu.c +++ b/drivers/perf/marvell_cn10k_tad_pmu.c @@ -258,7 +258,7 @@ static ssize_t tad_pmu_cpumask_show(struct device *dev, { struct tad_pmu *tad_pmu = to_tad_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(tad_pmu->cpu))); } static DEVICE_ATTR(cpumask, 0444, tad_pmu_cpumask_show, NULL); diff --git a/drivers/perf/marvell_pem_pmu.c b/drivers/perf/marvell_pem_pmu.c index 29fbcd1848e4..cf1d8cdb1318 100644 --- a/drivers/perf/marvell_pem_pmu.c +++ b/drivers/perf/marvell_pem_pmu.c @@ -164,7 +164,7 @@ static ssize_t pem_perf_cpumask_show(struct device *dev, { struct pem_pmu *pmu = dev_get_drvdata(dev); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(pmu->cpu))); } static struct device_attribute pem_perf_cpumask_attr = diff --git a/drivers/perf/nvidia_t410_c2c_pmu.c b/drivers/perf/nvidia_t410_c2c_pmu.c index 411987153ff3..bff875f4f625 100644 --- a/drivers/perf/nvidia_t410_c2c_pmu.c +++ b/drivers/perf/nvidia_t410_c2c_pmu.c @@ -658,7 +658,7 @@ static ssize_t nv_c2c_pmu_cpumask_show(struct device *dev, default: return 0; } - return cpumap_print_to_pagebuf(true, buf, cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask)); } #define NV_C2C_PMU_CPUMASK_ATTR(_name, _config) \ diff --git a/drivers/perf/nvidia_t410_cmem_latency_pmu.c b/drivers/perf/nvidia_t410_cmem_latency_pmu.c index acb8f5571522..6c8e41598ec1 100644 --- a/drivers/perf/nvidia_t410_cmem_latency_pmu.c +++ b/drivers/perf/nvidia_t410_cmem_latency_pmu.c @@ -501,7 +501,7 @@ static ssize_t cmem_lat_pmu_cpumask_show(struct device *dev, default: return 0; } - return cpumap_print_to_pagebuf(true, buf, cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask)); } #define NV_PMU_CPUMASK_ATTR(_name, _config) \ diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c index 57a28ddb9b0e..29554cca22c5 100644 --- a/drivers/perf/qcom_l2_pmu.c +++ b/drivers/perf/qcom_l2_pmu.c @@ -638,7 +638,7 @@ static ssize_t l2_cache_pmu_cpumask_show(struct device *dev, { struct l2cache_pmu *l2cache_pmu = to_l2cache_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, &l2cache_pmu->cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&l2cache_pmu->cpumask)); } static struct device_attribute l2_cache_pmu_cpumask_attr = diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c index 5897ec5560fc..e18d0f94e8d8 100644 --- a/drivers/perf/qcom_l3_pmu.c +++ b/drivers/perf/qcom_l3_pmu.c @@ -663,7 +663,7 @@ static ssize_t cpumask_show(struct device *dev, { struct l3cache_pmu *l3pmu = to_l3cache_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, &l3pmu->cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&l3pmu->cpumask)); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/starfive_starlink_pmu.c b/drivers/perf/starfive_starlink_pmu.c index 57b73575c43f..98e5ccee2fdc 100644 --- a/drivers/perf/starfive_starlink_pmu.c +++ b/drivers/perf/starfive_starlink_pmu.c @@ -130,7 +130,7 @@ cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { struct starlink_pmu *starlink_pmu = to_starlink_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, &starlink_pmu->cpumask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&starlink_pmu->cpumask)); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c index 6ed4707bd6bb..a69c02d2d874 100644 --- a/drivers/perf/thunderx2_pmu.c +++ b/drivers/perf/thunderx2_pmu.c @@ -254,7 +254,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, struct tx2_uncore_pmu *tx2_pmu; tx2_pmu = pmu_to_tx2_pmu(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, cpumask_of(tx2_pmu->cpu)); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpumask_of(tx2_pmu->cpu))); } static DEVICE_ATTR_RO(cpumask); diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c index b79409c750e6..ab3623fab914 100644 --- a/drivers/perf/xgene_pmu.c +++ b/drivers/perf/xgene_pmu.c @@ -595,7 +595,7 @@ static ssize_t cpumask_show(struct device *dev, { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(dev_get_drvdata(dev)); - return cpumap_print_to_pagebuf(true, buf, &pmu_dev->parent->cpu); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&pmu_dev->parent->cpu)); } static DEVICE_ATTR_RO(cpumask); diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h index d51beff60375..e3b0da9a25f1 100644 --- a/include/asm-generic/bitops/le.h +++ b/include/asm-generic/bitops/le.h @@ -16,47 +16,47 @@ #endif -static inline int test_bit_le(int nr, const void *addr) +static inline int test_bit_le(unsigned long nr, const void *addr) { return test_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline void set_bit_le(int nr, void *addr) +static inline void set_bit_le(unsigned long nr, void *addr) { set_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline void clear_bit_le(int nr, void *addr) +static inline void clear_bit_le(unsigned long nr, void *addr) { clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline void __set_bit_le(int nr, void *addr) +static inline void __set_bit_le(unsigned long nr, void *addr) { __set_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline void __clear_bit_le(int nr, void *addr) +static inline void __clear_bit_le(unsigned long nr, void *addr) { __clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline int test_and_set_bit_le(int nr, void *addr) +static inline int test_and_set_bit_le(unsigned long nr, void *addr) { return test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline int test_and_clear_bit_le(int nr, void *addr) +static inline int test_and_clear_bit_le(unsigned long nr, void *addr) { return test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline int __test_and_set_bit_le(int nr, void *addr) +static inline int __test_and_set_bit_le(unsigned long nr, void *addr) { return __test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr); } -static inline int __test_and_clear_bit_le(int nr, void *addr) +static inline int __test_and_clear_bit_le(unsigned long nr, void *addr) { return __test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); } diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index b007d54a9036..7df1573a409c 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -2,7 +2,7 @@ #ifndef __LINUX_BITMAP_H #define __LINUX_BITMAP_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include #include @@ -209,6 +209,9 @@ unsigned long bitmap_find_next_zero_area_off(unsigned long *map, * The @align_mask should be one less than a power of 2; the effect is that * the bit offset of all zero areas this function finds is multiples of that * power of 2. A @align_mask of 0 means no alignment is required. + * + * Return: The bit offset of the found area or a value >= @size + * if no area is found. */ static __always_inline unsigned long bitmap_find_next_zero_area(unsigned long *map, @@ -697,14 +700,6 @@ void bitmap_gather(unsigned long *dst, const unsigned long *src, __assign_bit(n++, dst, test_bit(bit, src)); } -static __always_inline -void bitmap_next_set_region(unsigned long *bitmap, unsigned int *rs, - unsigned int *re, unsigned int end) -{ - *rs = find_next_bit(bitmap, end, *rs); - *re = find_next_zero_bit(bitmap, end, *rs + 1); -} - /** * bitmap_release_region - release allocated bitmap region * @bitmap: array of unsigned longs corresponding to the bitmap @@ -894,6 +889,6 @@ void bitmap_write(unsigned long *map, unsigned long value, #define bitmap_set_value8(map, value, start) \ bitmap_write(map, value, start, BITS_PER_BYTE) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __LINUX_BITMAP_H */ diff --git a/include/linux/bits.h b/include/linux/bits.h index a40cc861b3a7..b7509f15718e 100644 --- a/include/linux/bits.h +++ b/include/linux/bits.h @@ -17,7 +17,7 @@ * position @h. For example * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */ -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) /* * Missing asm support @@ -75,7 +75,7 @@ #define BIT_U32(nr) BIT_TYPE(u32, nr) #define BIT_U64(nr) BIT_TYPE(u64, nr) -#else /* defined(__ASSEMBLY__) */ +#else /* defined(__ASSEMBLER__) */ /* * BUILD_BUG_ON_ZERO is not available in h files included from asm files, @@ -84,6 +84,6 @@ #define GENMASK(h, l) __GENMASK(h, l) #define GENMASK_ULL(h, l) __GENMASK_ULL(h, l) -#endif /* !defined(__ASSEMBLY__) */ +#endif /* !defined(__ASSEMBLER__) */ #endif /* __LINUX_BITS_H */ diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index d3cda0544954..4c8bb6953107 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -1315,24 +1314,6 @@ static __always_inline bool cpu_dying(unsigned int cpu) } #endif /* NR_CPUS > BITS_PER_LONG */ -/** - * cpumap_print_to_pagebuf - copies the cpumask into the buffer either - * as comma-separated list of cpus or hex values of cpumask - * @list: indicates whether the cpumap must be list - * @mask: the cpumask to copy - * @buf: the buffer to copy into - * - * Return: the length of the (null-terminated) @buf string, zero if - * nothing is copied. - */ -static __always_inline ssize_t -cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) -{ - /* Opencode offset_in_page(buf) to not include linux/mm.h */ - return scnprintf(buf, PAGE_SIZE - ((unsigned long)buf & ~PAGE_MASK), - list ? "%*pbl\n" : "%*pb\n", cpumask_pr_args(mask)); -} - /** * cpumap_print_bitmask_to_buf - copies the cpumask into the buffer as * hex values of cpumask diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index b842aa525546..607373bd83ee 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -95,6 +95,14 @@ extern nodemask_t _unused_nodemask_arg_; +#if MAX_NUMNODES > 1 +extern unsigned int nr_node_ids; +extern unsigned int nr_online_nodes; +#else +#define nr_node_ids 1U +#define nr_online_nodes 1U +#endif + /** * nodemask_pr_args - printf args to output a nodemask * @maskp: nodemask to be printed @@ -105,7 +113,7 @@ extern nodemask_t _unused_nodemask_arg_; __nodemask_pr_bits(maskp) static __always_inline unsigned int __nodemask_pr_numnodes(const nodemask_t *m) { - return m ? MAX_NUMNODES : 0; + return m ? nr_node_ids : 0; } static __always_inline const unsigned long *__nodemask_pr_bits(const nodemask_t *m) { @@ -438,9 +446,6 @@ static __always_inline unsigned int next_memory_node(int nid) return next_node(nid, node_states[N_MEMORY]); } -extern unsigned int nr_node_ids; -extern unsigned int nr_online_nodes; - static __always_inline void node_set_online(int nid) { node_set_state(nid, N_ONLINE); @@ -480,8 +485,6 @@ static __always_inline int num_node_state(enum node_states state) #define first_memory_node 0 #define next_online_node(nid) (MAX_NUMNODES) #define next_memory_node(nid) (MAX_NUMNODES) -#define nr_node_ids 1U -#define nr_online_nodes 1U #define node_set_online(node) node_set_state((node), N_ONLINE) #define node_set_offline(node) node_clear_state((node), N_ONLINE) diff --git a/kernel/events/core.c b/kernel/events/core.c index 2eee83cdb43d..421b897de71e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -12726,7 +12726,7 @@ static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, struct cpumask *mask = perf_scope_cpumask(pmu->scope); if (mask) - return cpumap_print_to_pagebuf(true, buf, mask); + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(mask)); return 0; } diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 73287ef2498c..6ea441f2fade 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2683,6 +2683,19 @@ config FIND_BIT_BENCHMARK If unsure, say N. +config REGION_ALLOC_BENCHMARK + tristate "Benchmark bitmap, IDA and Maple Tree region allocation" + help + This builds a microbenchmark comparing variable-sized region + allocation using bitmaps, IDA and Maple Tree. The benchmark + runs at initialization time. + + Usage: + insmod region_alloc_benchmark.ko + insmod region_alloc_benchmark.ko capacities=1024,2048,4096,65536 + + If unsure, say N. + config FIND_BIT_BENCHMARK_RUST tristate "Test find_bit functions in Rust" depends on RUST diff --git a/lib/Makefile b/lib/Makefile index 7f75cc6edf94..adb18810e3f7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -64,6 +64,7 @@ obj-y += hexdump.o obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o obj-y += kstrtox.o obj-$(CONFIG_FIND_BIT_BENCHMARK) += find_bit_benchmark.o +obj-$(CONFIG_REGION_ALLOC_BENCHMARK) += region_alloc_benchmark.o obj-$(CONFIG_FIND_BIT_BENCHMARK_RUST) += find_bit_benchmark_rust.o obj-$(CONFIG_TEST_BPF) += test_bpf.o test_dhry-objs := dhry_1.o dhry_2.o dhry_run.o diff --git a/lib/bitmap-str.c b/lib/bitmap-str.c index 26d36c938c6a..dd9aa0635fa5 100644 --- a/lib/bitmap-str.c +++ b/lib/bitmap-str.c @@ -75,8 +75,7 @@ static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp, * @off: in the string from which we are copying, We copy to @buf * @count: the maximum number of bytes to print * - * The sprintf("%*pb[l]") is used indirectly via its cpumap wrapper - * cpumap_print_to_pagebuf() or directly by drivers to export hexadecimal + * The sprintf("%*pb[l]") format is used by drivers to export hexadecimal * bitmask and decimal list to userspace by sysfs ABI. * Drivers might be using a normal attribute for this kind of ABIs. A * normal attribute typically has show entry as below:: @@ -115,9 +114,9 @@ static int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp, * parameters such as off, count from bin_attribute show entry to this API. * * The role of cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf() - * is similar with cpumap_print_to_pagebuf(), the difference is that - * scnprintf("%*pb[l]") mainly serves sysfs attribute with the assumption - * the destination buffer is exactly one page and won't be more than one page. + * is similar to direct sysfs_emit("%*pb[l]") formatting, but the latter + * assumes the destination buffer is exactly one page and won't be more than + * one page. * cpumap_print_bitmask_to_buf() and cpumap_print_list_to_buf(), on the other * hand, mainly serves bin_attribute which doesn't work with exact one page, * and it can break the size limit of converted decimal list and hexadecimal diff --git a/lib/bitmap.c b/lib/bitmap.c index b9bfa157e095..ed685127a107 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -424,6 +424,9 @@ EXPORT_SYMBOL(__bitmap_clear); * The @align_mask should be one less than a power of 2; the effect is that * the bit offset of all zero areas this function finds plus @align_offset * is multiple of that power of 2. + * + * Return: The bit offset of the found area or a value greater than or equal + * to @size if no area is found. */ unsigned long bitmap_find_next_zero_area_off(unsigned long *map, unsigned long size, @@ -432,22 +435,23 @@ unsigned long bitmap_find_next_zero_area_off(unsigned long *map, unsigned long align_mask, unsigned long align_offset) { - unsigned long index, end, i; -again: - index = find_next_zero_bit(map, size, start); + unsigned long end, i, off; - /* Align allocation */ - index = __ALIGN_MASK(index + align_offset, align_mask) - align_offset; + for_each_clear_bit_from(start, map, size) { + start = __ALIGN_MASK(start + align_offset, align_mask) - align_offset; + end = start + nr; + if (end > size) + break; - end = index + nr; - if (end > size) - return end; - i = find_next_bit(map, end, index); - if (i < end) { - start = i + 1; - goto again; + off = round_down(start, BITS_PER_LONG); + i = find_last_bit(map + start / BITS_PER_LONG, end - off) + off; + if (i >= end || i < start) + return start; + + start = i; } - return index; + + return size; } EXPORT_SYMBOL(bitmap_find_next_zero_area_off); diff --git a/lib/find_bit_benchmark.c b/lib/find_bit_benchmark.c index 00d9dc61cd46..05305e655f99 100644 --- a/lib/find_bit_benchmark.c +++ b/lib/find_bit_benchmark.c @@ -149,6 +149,21 @@ static int __init test_find_next_and_bit(const void *bitmap, return 0; } +static int __init +test_bitmap_find_next_zero_area_off(unsigned long *bitmap, unsigned long len) +{ + unsigned long i, cnt; + ktime_t time; + + time = ktime_get(); + for (cnt = i = 0; i < BITMAP_LEN; cnt++) + i = bitmap_find_next_zero_area_off(bitmap, BITMAP_LEN, i, 8, 0, 0) + 1; + time = ktime_get() - time; + pr_err("bitmap_find_next_zero_area_off:%7llu ns, %6ld iterations\n", time, cnt); + + return 0; +} + static int __init find_bit_test(void) { unsigned long nbits = BITMAP_LEN / SPARSE; @@ -158,6 +173,7 @@ static int __init find_bit_test(void) get_random_bytes(bitmap, sizeof(bitmap)); get_random_bytes(bitmap2, sizeof(bitmap2)); + test_bitmap_find_next_zero_area_off(bitmap, BITMAP_LEN); test_find_next_bit(bitmap, BITMAP_LEN); test_find_next_zero_bit(bitmap, BITMAP_LEN); test_find_last_bit(bitmap, BITMAP_LEN); @@ -181,6 +197,7 @@ static int __init find_bit_test(void) __set_bit(get_random_u32_below(BITMAP_LEN), bitmap2); } + test_bitmap_find_next_zero_area_off(bitmap, BITMAP_LEN); test_find_next_bit(bitmap, BITMAP_LEN); test_find_next_zero_bit(bitmap, BITMAP_LEN); test_find_last_bit(bitmap, BITMAP_LEN); diff --git a/lib/region_alloc_benchmark.c b/lib/region_alloc_benchmark.c new file mode 100644 index 000000000000..e88b4cf55c62 --- /dev/null +++ b/lib/region_alloc_benchmark.c @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Benchmark bitmap, IDA and Maple Tree allocation of variable-sized regions. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REGION_MAX_SIZE 32 + +static unsigned long *bitmap __initdata; +/* One more request guarantees that even an all-ones trace reaches ENOSPC. */ +static u8 *reg_sz __initdata; +static unsigned long *reg_idx __initdata; +static unsigned long capacities[64] = { 1000000, 100000, 10000, 1000, 100, 10 }; +static unsigned int cap_cnt = 6; + +module_param_array(capacities, ulong, &cap_cnt, 0400); +MODULE_PARM_DESC(capacities, "Region capacities to benchmark"); + +static unsigned long __init benchmark_bitmap(unsigned long cap) +{ + unsigned long cnt, idx; + ktime_t alloc_time, free_time; + size_t sz; + + bitmap_zero(bitmap, cap); + alloc_time = ktime_get(); + for (cnt = 0; cnt <= cap; cnt++) { + idx = bitmap_find_next_zero_area(bitmap, cap, 0, reg_sz[cnt], 0); + if (idx >= cap) + break; + + reg_idx[cnt] = idx; + bitmap_set(bitmap, idx, reg_sz[cnt]); + } + alloc_time = ktime_get() - alloc_time; + + idx = cnt; + + free_time = ktime_get(); + while (idx--) + bitmap_clear(bitmap, reg_idx[idx], reg_sz[idx]); + free_time = ktime_get() - free_time; + + WARN_ON(!bitmap_empty(bitmap, cap)); + + sz = BITS_TO_LONGS(cap) * sizeof(unsigned long); + pr_err("Bitmap %12llu %12llu %8lu %8lu %10zu\n", + alloc_time, free_time, cnt, cap, sz); + + return cnt; +} + +static size_t __init ida_size(unsigned long nr_ids) +{ + unsigned long entries = DIV_ROUND_UP(nr_ids, IDA_BITMAP_BITS); + unsigned long bitmaps = nr_ids / IDA_BITMAP_BITS; + unsigned long nodes = 0; + + if (nr_ids % IDA_BITMAP_BITS > BITS_PER_XA_VALUE) + bitmaps++; + + while (entries > 1) { + entries = DIV_ROUND_UP(entries, XA_CHUNK_SIZE); + nodes += entries; + } + + return sizeof(struct ida) + + bitmaps * sizeof(struct ida_bitmap) + + nodes * sizeof(struct xa_node); +} + +static unsigned long __init benchmark_ida(unsigned long cap) +{ + struct ida ida = IDA_INIT(ida); + unsigned long cnt, idx, off, nr_ids = 0; + ktime_t alloc_time, free_time; + int id = -ENOSPC; + + alloc_time = ktime_get(); + for (cnt = 0; cnt <= cap; cnt++) { + for (off = 0; off < reg_sz[cnt]; off++) { + id = ida_alloc_max(&ida, cap - 1, GFP_KERNEL); + if (id < 0) + break; + + if (!off) + reg_idx[cnt] = id; + } + if (id < 0) { + while (off--) + ida_free(&ida, reg_idx[cnt] + off); + break; + } + WARN_ON(id != reg_idx[cnt] + reg_sz[cnt] - 1); + nr_ids += reg_sz[cnt]; + } + alloc_time = ktime_get() - alloc_time; + + WARN_ON(id != -ENOSPC); + + idx = cnt; + + free_time = ktime_get(); + while (idx--) { + for (off = 0; off < reg_sz[idx]; off++) + ida_free(&ida, reg_idx[idx] + off); + } + free_time = ktime_get() - free_time; + + WARN_ON(!ida_is_empty(&ida)); + + pr_err("IDA %12llu %12llu %8lu %8lu %10zu\n", + alloc_time, free_time, cnt, cap, ida_size(nr_ids)); + + ida_destroy(&ida); + return cnt; +} + +static unsigned long __init benchmark_maple_tree(unsigned long cap) +{ + struct maple_tree mt = MTREE_INIT(mt, MT_FLAGS_ALLOC_RANGE); + unsigned long cnt, idx; + ktime_t alloc_time, free_time; + size_t sz; + int ret; + + alloc_time = ktime_get(); + for (cnt = 0; cnt <= cap; cnt++) { + ret = mtree_alloc_range(&mt, &idx, xa_mk_value(cnt + 1), + reg_sz[cnt], 0, cap - 1, GFP_KERNEL); + if (ret) + break; + + reg_idx[cnt] = idx; + } + alloc_time = ktime_get() - alloc_time; + + WARN_ON(ret != -EBUSY); + + idx = cnt; + + free_time = ktime_get(); + while (idx--) + mtree_erase(&mt, reg_idx[idx]); + free_time = ktime_get() - free_time; + + WARN_ON(!mtree_empty(&mt)); + + /* Minimum storage assuming fully occupied allocation-range leaf nodes. */ + sz = sizeof(mt) + DIV_ROUND_UP(cnt, MAPLE_ARANGE64_SLOTS) * sizeof(struct maple_node); + pr_err("Maple %12llu %12llu %8lu %8lu %10zu\n", + alloc_time, free_time, cnt, cap, sz); + + mtree_destroy(&mt); + return cnt; +} + +static int __init region_alloc_benchmark(void) +{ + unsigned long bitmap_count, ida_count, maple_count; + unsigned long i, max_cap = 0; + int ret = -ENOMEM; + + for (i = 0; i < cap_cnt; i++) { + if (capacities[i] == 0) { + pr_err("capacity must be nonzero\n"); + return -EINVAL; + } + max_cap = max(max_cap, capacities[i]); + } + + bitmap = kvmalloc_array(BITS_TO_LONGS(max_cap), sizeof(*bitmap), GFP_KERNEL); + reg_sz = kvmalloc_array(max_cap + 1, sizeof(*reg_sz), GFP_KERNEL); + reg_idx = kvmalloc_array(max_cap, sizeof(*reg_idx), GFP_KERNEL); + if (!bitmap || !reg_sz || !reg_idx) + goto out; + + pr_err("\nStart testing bitmap vs IDA vs Maple Tree region allocation\n"); + pr_err("memory: bitmap is exact; IDA and Maple Tree are lower bounds\n"); + pr_err("Type alloc (ns) free (ns) regions capacity memory (B)\n"); + + for (i = 0; i < cap_cnt; i++) { + unsigned long idx, max_size; + + max_size = min(REGION_MAX_SIZE, capacities[i] / 10) ? : 1; + for (idx = 0; idx <= capacities[i]; idx++) + reg_sz[idx] = get_random_u32_below(max_size) + 1; + + bitmap_count = benchmark_bitmap(capacities[i]); + maple_count = benchmark_maple_tree(capacities[i]); + ida_count = benchmark_ida(capacities[i]); + + WARN_ON(bitmap_count != ida_count); + WARN_ON(bitmap_count != maple_count); + } + + /* Return an error so the benchmark can run repeatedly without rmmod. */ + pr_info("Region allocation benchmark complete\n"); + ret = -EAGAIN; +out: + kvfree(reg_idx); + kvfree(reg_sz); + kvfree(bitmap); + return ret; +} +module_init(region_alloc_benchmark); + +MODULE_AUTHOR("Yury Norov "); +MODULE_DESCRIPTION("Benchmark bitmap, IDA and Maple Tree region allocation"); +MODULE_LICENSE("GPL"); diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index 69813c10e6c0..56bd23059b26 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c @@ -234,6 +234,43 @@ static void __init test_find_nth_bit(void) } } +static void __init +test_bitmap_find_next_zero_area_off(void) +{ + DECLARE_BITMAP(bmap, 192); + + bitmap_set(bmap, 0, 192); + + bitmap_clear(bmap, 0, 8); + __clear_bit(50, bmap); + bitmap_clear(bmap, 60, 18); + __set_bit(69, bmap); + __clear_bit(80, bmap); + bitmap_clear(bmap, 100, 10); + __clear_bit(120, bmap); + bitmap_clear(bmap, 145, 8); + bitmap_clear(bmap, 160, 32); + + expect_eq_uint(0, + bitmap_find_next_zero_area_off(bmap, 192, 0, 8, 0, 0)); + expect_eq_uint(0, + bitmap_find_next_zero_area_off(bmap, 192, 0, 8, 3, 0)); + expect_eq_uint(163, + bitmap_find_next_zero_area_off(bmap, 192, 0, 8, 3, 1)); + expect_eq_uint(60, + bitmap_find_next_zero_area_off(bmap, 192, 1, 8, 0, 0)); + expect_eq_uint(160, + bitmap_find_next_zero_area_off(bmap, 192, 1, 8, 7, 0)); + expect_eq_uint(60, + bitmap_find_next_zero_area_off(bmap, 192, 1, 8, 7, 4)); + expect_eq_uint(100, + bitmap_find_next_zero_area_off(bmap, 192, 0, 10, 0, 0)); + expect_eq_uint(160, + bitmap_find_next_zero_area_off(bmap, 192, 0, 32, 0, 0)); + expect_eq_uint(1, + !!(bitmap_find_next_zero_area_off(bmap, 192, 0, 33, 0, 0) >= 192)); +} + static void __init test_fill_set(void) { DECLARE_BITMAP(bmap, 1024); @@ -392,6 +429,7 @@ static void __init test_bitmap_sg(void) /* Scatter/gather relationship */ bitmap_zero(bmap_tmp, 100); + bitmap_zero(bmap_res, 100); bitmap_gather(bmap_tmp, bmap_scatter, sg_mask, nbits); bitmap_scatter(bmap_res, bmap_tmp, sg_mask, nbits); expect_eq_bitmap(bmap_scatter, bmap_res, 100); @@ -1559,6 +1597,7 @@ static void __init selftest(void) test_for_each_clear_bitrange_from(); test_for_each_set_clump8(); test_for_each_set_bit_wrap(); + test_bitmap_find_next_zero_area_off(); } KSTM_MODULE_LOADERS(test_bitmap); diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h index a40cc861b3a7..b7509f15718e 100644 --- a/tools/include/linux/bits.h +++ b/tools/include/linux/bits.h @@ -17,7 +17,7 @@ * position @h. For example * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */ -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) /* * Missing asm support @@ -75,7 +75,7 @@ #define BIT_U32(nr) BIT_TYPE(u32, nr) #define BIT_U64(nr) BIT_TYPE(u64, nr) -#else /* defined(__ASSEMBLY__) */ +#else /* defined(__ASSEMBLER__) */ /* * BUILD_BUG_ON_ZERO is not available in h files included from asm files, @@ -84,6 +84,6 @@ #define GENMASK(h, l) __GENMASK(h, l) #define GENMASK_ULL(h, l) __GENMASK_ULL(h, l) -#endif /* !defined(__ASSEMBLY__) */ +#endif /* !defined(__ASSEMBLER__) */ #endif /* __LINUX_BITS_H */