• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * drivers/block/zram/zram_group/zlist.h
4  *
5  * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd.
6  */
7 
8 #ifndef _ZLIST_H_
9 #define _ZLIST_H_
10 
11 #define ZLIST_IDX_SHIFT 30
12 #define ZLIST_LOCK_BIT ZLIST_IDX_SHIFT
13 #define ZLIST_PRIV_BIT ((ZLIST_IDX_SHIFT << 1) + 1)
14 
15 #define ZLIST_IDX_MAX (1 << ZLIST_IDX_SHIFT)
16 
17 struct zlist_node {
18 	u64 prev	: ZLIST_IDX_SHIFT;
19 	u64 lock	: 1;
20 	u64 next	: ZLIST_IDX_SHIFT;
21 	u64 priv	: 1;
22 };
23 
24 struct zlist_table {
25 	struct zlist_node *(*idx2node)(u32 idx, void *priv);
26 	void *private;
27 };
28 
idx2node(u32 idx,struct zlist_table * tab)29 static inline struct zlist_node *idx2node(u32 idx, struct zlist_table *tab)
30 {
31 	return tab->idx2node(idx, tab->private);
32 }
33 
next_idx(u32 idx,struct zlist_table * tab)34 static inline u32 next_idx(u32 idx, struct zlist_table *tab)
35 {
36 	return idx2node(idx, tab)->next;
37 }
38 
prev_idx(u32 idx,struct zlist_table * tab)39 static inline u32 prev_idx(u32 idx, struct zlist_table *tab)
40 {
41 	return idx2node(idx, tab)->prev;
42 }
43 
zlist_table_free(struct zlist_table * tab)44 static inline void zlist_table_free(struct zlist_table *tab)
45 {
46 	kfree(tab);
47 }
48 
49 struct zlist_table *zlist_table_alloc(struct zlist_node *(*i2n)(u32, void*),
50 					void *private, gfp_t gfp);
51 
52 void zlist_lock(u32 idx, struct zlist_table *tab);
53 void zlist_unlock(u32 idx, struct zlist_table *tab);
54 
55 void zlist_add_nolock(u32 hid, u32 idx, struct zlist_table *tab);
56 void zlist_add_tail_nolock(u32 hid, u32 idx, struct zlist_table *tab);
57 bool zlist_del_nolock(u32 hid, u32 idx, struct zlist_table *tab);
58 bool zlist_is_isolated_nolock(u32 idx, struct zlist_table *tab);
59 
zlist_add(u32 hid,u32 idx,struct zlist_table * tab)60 static inline void zlist_add(u32 hid, u32 idx, struct zlist_table *tab)
61 {
62 	zlist_lock(hid, tab);
63 	zlist_add_nolock(hid, idx, tab);
64 	zlist_unlock(hid, tab);
65 }
66 
zlist_add_tail(u32 hid,u32 idx,struct zlist_table * tab)67 static inline void zlist_add_tail(u32 hid, u32 idx, struct zlist_table *tab)
68 {
69 	zlist_lock(hid, tab);
70 	zlist_add_tail_nolock(hid, idx, tab);
71 	zlist_unlock(hid, tab);
72 }
73 
zlist_del(u32 hid,u32 idx,struct zlist_table * tab)74 static inline bool zlist_del(u32 hid, u32 idx, struct zlist_table *tab)
75 {
76 	bool ret = false;
77 
78 	zlist_lock(hid, tab);
79 	ret = zlist_del_nolock(hid, idx, tab);
80 	zlist_unlock(hid, tab);
81 
82 	return ret;
83 }
84 
85 bool zlist_set_priv(u32 idx, struct zlist_table *tab);
86 bool zlist_clr_priv_nolock(u32 idx, struct zlist_table *tab);
87 bool zlist_test_priv_nolock(u32 idx, struct zlist_table *tab);
88 
89 void zlist_node_init(u32 idx, struct zlist_table *tab);
90 
91 #define zlist_for_each_entry(idx, hid, tab) \
92 	for ((idx) = next_idx(hid, tab); (idx) != (hid);  \
93 		(idx) = next_idx(idx, tab))
94 #define zlist_for_each_entry_reverse(idx, hid, tab) \
95 	for ((idx) = prev_idx(hid, tab); (idx) != (hid);  \
96 		(idx) = prev_idx(idx, tab))
97 #endif
98