// SPDX-License-Identifier: GPL-2.0-only
/*
 * Test for find_*_bit functions.
 *
 * Copyright (c) 2017 Cavium.
 */

/*
 * find_bit functions are widely used in kernel, so the successful boot
 * is good enough test for correctness.
 *
 * This test is focused on performance of traversing bitmaps. Two typical
 * scenarios are reproduced:
 * - randomly filled bitmap with approximately equal number of set and
 *   cleared bits;
 * - sparse bitmap with few set bits at random positions.
 */

#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/random.h>

#define BITMAP_LEN	(4096UL * 8 * 10)
#define SPARSE		500

static DECLARE_BITMAP(bitmap, BITMAP_LEN) __initdata;
static DECLARE_BITMAP(bitmap2, BITMAP_LEN) __initdata;

/*
 * This is Schlemiel the Painter's algorithm.
 */
static int __init test_find_first_bit(const void *bitmap, unsigned long len)
{
	static DECLARE_BITMAP(cp, BITMAP_LEN) __initdata;
	unsigned long i, cnt;
	ktime_t time;

	bitmap_copy(cp, bitmap, BITMAP_LEN);

	time = ktime_get();
	for (cnt = i = 0; i < len; cnt++) {
		i = find_first_bit(cp, len);
		__clear_bit(i, cp);
	}
	time = ktime_get() - time;
	pr_err("find_first_bit:     %18llu ns, %6ld iterations\n", time, cnt);

	return 0;
}

static int __init test_find_first_and_bit(const void *bitmap, const void *bitmap2,
		unsigned long len)
{
	static DECLARE_BITMAP(cp, BITMAP_LEN) __initdata;
	unsigned long i, cnt;
	ktime_t time;

	bitmap_copy(cp, bitmap, BITMAP_LEN);

	time = ktime_get();
	for (cnt = i = 0; i < len; cnt++) {
		i = find_first_and_bit(cp, bitmap2, len);
		__clear_bit(i, cp);
	}
	time = ktime_get() - time;
	pr_err("find_first_and_bit: %18llu ns, %6ld iterations\n", time, cnt);

	return 0;
}

static int __init test_find_next_bit(const void *bitmap, unsigned long len)
{
	unsigned long i, cnt;
	ktime_t time;

	time = ktime_get();
	for (cnt = i = 0; i < BITMAP_LEN; cnt++)
		i = find_next_bit(bitmap, BITMAP_LEN, i) + 1;
	time = ktime_get() - time;
	pr_err("find_next_bit:      %18llu ns, %6ld iterations\n", time, cnt);

	return 0;
}

static int __init test_find_next_zero_bit(const void *bitmap, unsigned long len)
{
	unsigned long i, cnt;
	ktime_t time;

	time = ktime_get();
	for (cnt = i = 0; i < BITMAP_LEN; cnt++)
		i = find_next_zero_bit(bitmap, len, i) + 1;
	time = ktime_get() - time;
	pr_err("find_next_zero_bit: %18llu ns, %6ld iterations\n", time, cnt);

	return 0;
}

static int __init test_find_last_bit(const void *bitmap, unsigned long len)
{
	unsigned long l, cnt = 0;
	ktime_t time;

	time = ktime_get();
	do {
		cnt++;
		l = find_last_bit(bitmap, len);
		if (l >= len)
			break;
		len = l;
	} while (len);
	time = ktime_get() - time;
	pr_err("find_last_bit:      %18llu ns, %6ld iterations\n", time, cnt);

	return 0;
}

static int __init test_find_nth_bit(const unsigned long *bitmap, unsigned long len)
{
	unsigned long l, n, w = bitmap_weight(bitmap, len);
	ktime_t time;

	time = ktime_get();
	for (n = 0; n < w; n++) {
		l = find_nth_bit(bitmap, len, n);
		WARN_ON(l >= len);
	}
	time = ktime_get() - time;
	pr_err("find_nth_bit:       %18llu ns, %6ld iterations\n", time, w);

	return 0;
}

static int __init test_find_next_and_bit(const void *bitmap,
		const void *bitmap2, unsigned long len)
{
	unsigned long i, cnt;
	ktime_t time;

	time = ktime_get();
	for (cnt = i = 0; i < BITMAP_LEN; cnt++)
		i = find_next_and_bit(bitmap, bitmap2, BITMAP_LEN, i + 1);
	time = ktime_get() - time;
	pr_err("find_next_and_bit:  %18llu ns, %6ld iterations\n", time, cnt);

	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;

	pr_err("\nStart testing find_bit() with random-filled bitmap\n");

	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);
	test_find_nth_bit(bitmap, BITMAP_LEN / 10);

	/*
	 * test_find_first_bit() may take some time, so
	 * traverse only part of bitmap to avoid soft lockup.
	 */
	test_find_first_bit(bitmap, BITMAP_LEN / 10);
	test_find_first_and_bit(bitmap, bitmap2, BITMAP_LEN / 2);
	test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN);

	pr_err("\nStart testing find_bit() with sparse bitmap\n");

	bitmap_zero(bitmap, BITMAP_LEN);
	bitmap_zero(bitmap2, BITMAP_LEN);

	while (nbits--) {
		__set_bit(get_random_u32_below(BITMAP_LEN), bitmap);
		__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);
	test_find_nth_bit(bitmap, BITMAP_LEN);
	test_find_first_bit(bitmap, BITMAP_LEN);
	test_find_first_and_bit(bitmap, bitmap2, BITMAP_LEN);
	test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN);

	/*
	 * Everything is OK. Return error just to let user run benchmark
	 * again without annoying rmmod.
	 */
	return -EINVAL;
}
module_init(find_bit_test);

MODULE_DESCRIPTION("Test for find_*_bit functions");
MODULE_LICENSE("GPL");
