xref: /linux/drivers/md/dm-pcache/backing_dev.h (revision 68a052239fc4b351e961f698b824f7654a346091)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef _BACKING_DEV_H
3 #define _BACKING_DEV_H
4 
5 #include <linux/device-mapper.h>
6 
7 #include "pcache_internal.h"
8 
9 struct pcache_backing_dev_req;
10 typedef void (*backing_req_end_fn_t)(struct pcache_backing_dev_req *backing_req, int ret);
11 
12 #define BACKING_DEV_REQ_TYPE_REQ		1
13 #define BACKING_DEV_REQ_TYPE_KMEM		2
14 
15 #define BACKING_DEV_REQ_INLINE_BVECS		4
16 
17 struct pcache_request;
18 struct pcache_backing_dev_req {
19 	u8				type;
20 	struct bio			bio;
21 	struct pcache_backing_dev	*backing_dev;
22 
23 	void				*priv_data;
24 	backing_req_end_fn_t		end_req;
25 
26 	struct list_head		node;
27 	int				ret;
28 
29 	union {
30 		struct {
31 			struct pcache_request		*upper_req;
32 			u32				bio_off;
33 		} req;
34 		struct {
35 			struct bio_vec	inline_bvecs[BACKING_DEV_REQ_INLINE_BVECS];
36 			struct bio_vec	*bvecs;
37 			u32		n_vecs;
38 		} kmem;
39 	};
40 };
41 
42 struct pcache_backing_dev {
43 	struct pcache_cache		*cache;
44 
45 	struct dm_dev			*dm_dev;
46 	mempool_t			req_pool;
47 	mempool_t			bvec_pool;
48 
49 	struct list_head		submit_list;
50 	spinlock_t			submit_lock;
51 	struct work_struct		req_submit_work;
52 
53 	struct list_head		complete_list;
54 	spinlock_t			complete_lock;
55 	struct work_struct		req_complete_work;
56 
57 	atomic_t			inflight_reqs;
58 	wait_queue_head_t		inflight_wq;
59 
60 	u64				dev_size;
61 };
62 
63 struct dm_pcache;
64 int backing_dev_start(struct dm_pcache *pcache);
65 void backing_dev_stop(struct dm_pcache *pcache);
66 
67 struct pcache_backing_dev_req_opts {
68 	u32 type;
69 	union {
70 		struct {
71 			struct pcache_request *upper_req;
72 			u32 req_off;
73 			u32 len;
74 		} req;
75 		struct {
76 			void *data;
77 			blk_opf_t opf;
78 			u32 len;
79 			u64 backing_off;
80 		} kmem;
81 	};
82 
83 	gfp_t gfp_mask;
84 	backing_req_end_fn_t	end_fn;
85 	void			*priv_data;
86 };
87 
88 static inline u32 backing_dev_req_coalesced_max_len(const void *data, u32 len)
89 {
90 	const void *p = data;
91 	u32 done = 0, in_page, to_advance;
92 	struct page *first_page, *next_page;
93 
94 	if (!is_vmalloc_addr(data))
95 		return len;
96 
97 	first_page = vmalloc_to_page(p);
98 advance:
99 	in_page = PAGE_SIZE - offset_in_page(p);
100 	to_advance = min_t(u32, in_page, len - done);
101 
102 	done += to_advance;
103 	p += to_advance;
104 
105 	if (done == len)
106 		return done;
107 
108 	next_page = vmalloc_to_page(p);
109 	if (zone_device_pages_have_same_pgmap(first_page, next_page))
110 		goto advance;
111 
112 	return done;
113 }
114 
115 void backing_dev_req_submit(struct pcache_backing_dev_req *backing_req, bool direct);
116 void backing_dev_req_end(struct pcache_backing_dev_req *backing_req);
117 struct pcache_backing_dev_req *backing_dev_req_create(struct pcache_backing_dev *backing_dev,
118 						struct pcache_backing_dev_req_opts *opts);
119 struct pcache_backing_dev_req *backing_dev_req_alloc(struct pcache_backing_dev *backing_dev,
120 						struct pcache_backing_dev_req_opts *opts);
121 void backing_dev_req_init(struct pcache_backing_dev_req *backing_req,
122 			struct pcache_backing_dev_req_opts *opts);
123 void backing_dev_flush(struct pcache_backing_dev *backing_dev);
124 
125 int pcache_backing_init(void);
126 void pcache_backing_exit(void);
127 #endif /* _BACKING_DEV_H */
128