tools/testing/selftests/net/busy_poller.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/busy_poller.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/busy_poller.c
Extension
.c
Size
9590 bytes
Lines
369
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct epoll_params {
	uint32_t busy_poll_usecs;
	uint16_t busy_poll_budget;
	uint8_t prefer_busy_poll;

	/* pad the struct to a multiple of 64bits */
	uint8_t __pad;
};

#define EPOLL_IOC_TYPE 0x8A
#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params)
#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params)
#endif

static uint16_t cfg_port = 8000;
static struct in_addr cfg_bind_addr = { .s_addr = INADDR_ANY };
static char *cfg_outfile;
static int cfg_max_events = 8;
static uint32_t cfg_ifindex;

/* busy poll params */
static uint32_t cfg_busy_poll_usecs;
static uint16_t cfg_busy_poll_budget;
static uint8_t cfg_prefer_busy_poll;

/* NAPI params */
static uint32_t cfg_defer_hard_irqs;
static uint64_t cfg_gro_flush_timeout;
static uint64_t cfg_irq_suspend_timeout;
static enum netdev_napi_threaded cfg_napi_threaded_poll = NETDEV_NAPI_THREADED_DISABLED;

static void usage(const char *filepath)
{
	error(1, 0,
	      "Usage: %s -p<port> -b<addr> -m<max_events> -u<busy_poll_usecs> -P<prefer_busy_poll> -g<busy_poll_budget> -o<outfile> -d<defer_hard_irqs> -r<gro_flush_timeout> -s<irq_suspend_timeout> -t<napi_threaded_poll> -i<ifindex>",
	      filepath);
}

static void parse_opts(int argc, char **argv)
{
	unsigned long long tmp;
	int ret;
	int c;

	if (argc <= 1)
		usage(argv[0]);

	while ((c = getopt(argc, argv, "p:m:b:u:P:g:o:d:r:s:i:t:")) != -1) {
		/* most options take integer values, except o and b, so reduce
		 * code duplication a bit for the common case by calling
		 * strtoull here and leave bounds checking and casting per
		 * option below.
		 */
		if (c != 'o' && c != 'b')
			tmp = strtoull(optarg, NULL, 0);

		switch (c) {
		case 'u':
			if (tmp == ULLONG_MAX || tmp > UINT32_MAX)
				error(1, ERANGE, "busy_poll_usecs too large");

			cfg_busy_poll_usecs = (uint32_t)tmp;
			break;
		case 'P':
			if (tmp == ULLONG_MAX || tmp > 1)
				error(1, ERANGE,
				      "prefer busy poll should be 0 or 1");

			cfg_prefer_busy_poll = (uint8_t)tmp;
			break;
		case 'g':
			if (tmp == ULLONG_MAX || tmp > UINT16_MAX)
				error(1, ERANGE,
				      "busy poll budget must be [0, UINT16_MAX]");

			cfg_busy_poll_budget = (uint16_t)tmp;
			break;
		case 'p':
			if (tmp == ULLONG_MAX || tmp > UINT16_MAX)
				error(1, ERANGE, "port must be <= 65535");

			cfg_port = (uint16_t)tmp;
			break;
		case 'b':
			ret = inet_aton(optarg, &cfg_bind_addr);
			if (ret == 0)
				error(1, errno,
				      "bind address %s invalid", optarg);
			break;
		case 'o':

Annotation

Implementation Notes