mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 12:13:51 -04:00
Merge tag 'bitmap-for-7.3' of https://github.com/norov/linux
Pull bitmap updates from Yury Norov:
"The usual set of fixes, cleanups and performance improvements together
with a couple of new tests:
- bitmap_find_next_zero_area_off() optimization (Sunyi)
- bitmap_find_next_zero_area_off(): return size when no zero area is
found (Yury)
- bitmap vs IDA vs Maple Tree performance test (Yury)
- get rid of cpumap_print_to_pagebuf() (Yury)
- use nr_node_ids in __nodemask_pr_numnodes() (Li RongQing)
- bitops: make the *_bit_le functions use unsigned long (Benjamin)
- bitmap scatter & gather test fix (Christophe)
- use __ASSEMBLER__ in bitmap header files (Thomas)"
* tag 'bitmap-for-7.3' of https://github.com/norov/linux: (25 commits)
lib: test bitmap vs IDA vs Maple Tree performance for region allocations
bitmap: Return size when no zero area is found
media: s5p-mfc: Treat bitmap size as allocation failure
crypto: ccp: Treat bitmap size as allocation failure
powerpc/msi: Treat bitmap size as allocation failure
ARM: dma-mapping: Treat bitmap size as allocation failure
bitmap: drop bitmap_next_set_region()
nodemask: reduce bitmap width to nr_node_ids in __nodemask_pr_numnodes()
bitmap: Properly initialise destination bitmap for scatter & gather test
lib/bitmap-str: get rid of cpumap_print_to_pagebuf()
perf: Use sysfs_emit() for cpumask show callbacks
PCI/sysfs: Use sysfs_emit() for cpumask show callbacks
RDMA/hfi1: Use sysfs_emit() for cpumask show helper
hwtracing: hisi_ptt: Use sysfs_emit() for cpumask show
fpga: dfl-fme-perf: Use sysfs_emit() for cpumask show
devfreq: Use sysfs_emit() for cpumask show callbacks
cpu: Use sysfs_emit() for cpumask show callback
x86/events: Use sysfs_emit() for cpumask show callbacks
powerpc: Use sysfs_emit() for cpumask show callbacks
arm: Use sysfs_emit() for cpumask show callbacks
...
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#ifndef __LINUX_BITMAP_H
|
||||
#define __LINUX_BITMAP_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <linux/align.h>
|
||||
#include <linux/bitops.h>
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <linux/cpumask_types.h>
|
||||
#include <linux/gfp_types.h>
|
||||
#include <linux/numa.h>
|
||||
#include <linux/sprintf.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/types.h>
|
||||
#include <vdso/page.h>
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
30
lib/bitmap.c
30
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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
217
lib/region_alloc_benchmark.c
Normal file
217
lib/region_alloc_benchmark.c
Normal file
@@ -0,0 +1,217 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Benchmark bitmap, IDA and Maple Tree allocation of variable-sized regions. */
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/maple_tree.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/xarray.h>
|
||||
|
||||
#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 <ynorov@nvidia.com>");
|
||||
MODULE_DESCRIPTION("Benchmark bitmap, IDA and Maple Tree region allocation");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user