• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2021 SUSE LLC <mdoucha@suse.cz>
4  */
5 
6 #define TST_NO_DEFAULT_MAIN
7 #include "tst_test.h"
8 #include "tst_safe_io_uring.h"
9 
safe_io_uring_init(const char * file,const int lineno,unsigned int entries,struct io_uring_params * params,struct tst_io_uring * uring)10 int safe_io_uring_init(const char *file, const int lineno,
11 	unsigned int entries, struct io_uring_params *params,
12 	struct tst_io_uring *uring)
13 {
14 	errno = 0;
15 	uring->fd = io_uring_setup(entries, params);
16 
17 	if (uring->fd == -1) {
18 		if (errno == EOPNOTSUPP)
19 			tst_brk(TCONF, "CONFIG_IO_URING is not enabled");
20 
21 		tst_brk_(file, lineno, TBROK | TERRNO,
22 			"io_uring_setup() failed");
23 		return uring->fd;
24 	} else if (uring->fd < 0) {
25 		tst_brk_(file, lineno, TBROK | TERRNO,
26 			"io_uring_setup() returned invalid value %d",
27 			uring->fd);
28 		return uring->fd;
29 	}
30 
31 	uring->sqr_size = params->sq_entries;
32 	uring->cqr_size = params->cq_entries;
33 	uring->sqr_mapsize = params->sq_off.array +
34 		params->sq_entries * sizeof(__u32);
35 	uring->cqr_mapsize = params->cq_off.cqes +
36 		params->cq_entries * sizeof(struct io_uring_cqe);
37 
38 	uring->sqr_base = safe_mmap(file, lineno, NULL, uring->sqr_mapsize,
39 		PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, uring->fd,
40 		IORING_OFF_SQ_RING);
41 
42 	if (uring->sqr_base == MAP_FAILED)
43 		return -1;
44 
45 	uring->sqr_entries = safe_mmap(file, lineno, NULL,
46 		params->sq_entries * sizeof(struct io_uring_sqe),
47 		PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, uring->fd,
48 		IORING_OFF_SQES);
49 
50 	if (uring->sqr_entries == MAP_FAILED)
51 		return -1;
52 
53 	uring->cqr_base = safe_mmap(file, lineno, NULL, uring->cqr_mapsize,
54 		PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, uring->fd,
55 		IORING_OFF_CQ_RING);
56 
57 	if (uring->cqr_base == MAP_FAILED)
58 		return -1;
59 
60 	uring->sqr_head = uring->sqr_base + params->sq_off.head;
61 	uring->sqr_tail = uring->sqr_base + params->sq_off.tail;
62 	uring->sqr_mask = uring->sqr_base + params->sq_off.ring_mask;
63 	uring->sqr_flags = uring->sqr_base + params->sq_off.flags;
64 	uring->sqr_dropped = uring->sqr_base + params->sq_off.dropped;
65 	uring->sqr_array = uring->sqr_base + params->sq_off.array;
66 
67 	uring->cqr_head = uring->cqr_base + params->cq_off.head;
68 	uring->cqr_tail = uring->cqr_base + params->cq_off.tail;
69 	uring->cqr_mask = uring->cqr_base + params->cq_off.ring_mask;
70 	uring->cqr_overflow = uring->cqr_base + params->cq_off.overflow;
71 	uring->cqr_entries = uring->cqr_base + params->cq_off.cqes;
72 	return uring->fd;
73 }
74 
safe_io_uring_close(const char * file,const int lineno,struct tst_io_uring * uring)75 int safe_io_uring_close(const char *file, const int lineno,
76 	struct tst_io_uring *uring)
77 {
78 	int ret;
79 
80 	safe_munmap(file, lineno, NULL, uring->cqr_base, uring->cqr_mapsize);
81 	safe_munmap(file, lineno, NULL, uring->sqr_entries,
82 		uring->sqr_size * sizeof(struct io_uring_sqe));
83 	safe_munmap(file, lineno, NULL, uring->sqr_base, uring->sqr_mapsize);
84 	ret = safe_close(file, lineno, NULL, uring->fd);
85 	uring->fd = -1;
86 	return ret;
87 }
88 
safe_io_uring_enter(const char * file,const int lineno,int strict,int fd,unsigned int to_submit,unsigned int min_complete,unsigned int flags,sigset_t * sig)89 int safe_io_uring_enter(const char *file, const int lineno, int strict,
90 	int fd, unsigned int to_submit, unsigned int min_complete,
91 	unsigned int flags, sigset_t *sig)
92 {
93 	int ret;
94 
95 	errno = 0;
96 	ret = io_uring_enter(fd, to_submit, min_complete, flags, sig);
97 
98 	if (ret == -1) {
99 		tst_brk_(file, lineno, TBROK | TERRNO,
100 			"io_uring_enter() failed");
101 	} else if (ret < 0) {
102 		tst_brk_(file, lineno, TBROK | TERRNO,
103 			"Invalid io_uring_enter() return value %d", ret);
104 	} else if (strict && to_submit != (unsigned int)ret) {
105 		tst_brk_(file, lineno, TBROK,
106 			"io_uring_enter() submitted %d items (expected %d)",
107 			ret, to_submit);
108 	}
109 
110 	return ret;
111 }
112