xref: /openbmc/linux/io_uring/refs.h (revision ab1c84d8)
1e418bbc9SJens Axboe #ifndef IOU_REQ_REF_H
2e418bbc9SJens Axboe #define IOU_REQ_REF_H
3e418bbc9SJens Axboe 
4e418bbc9SJens Axboe #include <linux/atomic.h>
5*ab1c84d8SPavel Begunkov #include <linux/io_uring_types.h>
6e418bbc9SJens Axboe 
7e418bbc9SJens Axboe /*
8e418bbc9SJens Axboe  * Shamelessly stolen from the mm implementation of page reference checking,
9e418bbc9SJens Axboe  * see commit f958d7b528b1 for details.
10e418bbc9SJens Axboe  */
11e418bbc9SJens Axboe #define req_ref_zero_or_close_to_overflow(req)	\
12e418bbc9SJens Axboe 	((unsigned int) atomic_read(&(req->refs)) + 127u <= 127u)
13e418bbc9SJens Axboe 
req_ref_inc_not_zero(struct io_kiocb * req)14e418bbc9SJens Axboe static inline bool req_ref_inc_not_zero(struct io_kiocb *req)
15e418bbc9SJens Axboe {
16e418bbc9SJens Axboe 	WARN_ON_ONCE(!(req->flags & REQ_F_REFCOUNT));
17e418bbc9SJens Axboe 	return atomic_inc_not_zero(&req->refs);
18e418bbc9SJens Axboe }
19e418bbc9SJens Axboe 
req_ref_put_and_test(struct io_kiocb * req)20e418bbc9SJens Axboe static inline bool req_ref_put_and_test(struct io_kiocb *req)
21e418bbc9SJens Axboe {
22e418bbc9SJens Axboe 	if (likely(!(req->flags & REQ_F_REFCOUNT)))
23e418bbc9SJens Axboe 		return true;
24e418bbc9SJens Axboe 
25e418bbc9SJens Axboe 	WARN_ON_ONCE(req_ref_zero_or_close_to_overflow(req));
26e418bbc9SJens Axboe 	return atomic_dec_and_test(&req->refs);
27e418bbc9SJens Axboe }
28e418bbc9SJens Axboe 
req_ref_get(struct io_kiocb * req)29e418bbc9SJens Axboe static inline void req_ref_get(struct io_kiocb *req)
30e418bbc9SJens Axboe {
31e418bbc9SJens Axboe 	WARN_ON_ONCE(!(req->flags & REQ_F_REFCOUNT));
32e418bbc9SJens Axboe 	WARN_ON_ONCE(req_ref_zero_or_close_to_overflow(req));
33e418bbc9SJens Axboe 	atomic_inc(&req->refs);
34e418bbc9SJens Axboe }
35e418bbc9SJens Axboe 
__io_req_set_refcount(struct io_kiocb * req,int nr)36e418bbc9SJens Axboe static inline void __io_req_set_refcount(struct io_kiocb *req, int nr)
37e418bbc9SJens Axboe {
38e418bbc9SJens Axboe 	if (!(req->flags & REQ_F_REFCOUNT)) {
39e418bbc9SJens Axboe 		req->flags |= REQ_F_REFCOUNT;
40e418bbc9SJens Axboe 		atomic_set(&req->refs, nr);
41e418bbc9SJens Axboe 	}
42e418bbc9SJens Axboe }
43e418bbc9SJens Axboe 
io_req_set_refcount(struct io_kiocb * req)44e418bbc9SJens Axboe static inline void io_req_set_refcount(struct io_kiocb *req)
45e418bbc9SJens Axboe {
46e418bbc9SJens Axboe 	__io_req_set_refcount(req, 1);
47e418bbc9SJens Axboe }
48e418bbc9SJens Axboe #endif
49