- Possibility to operate with single size entries as well as control of the reclamat...
[mirror/scst/.git] / scst / src / scst_mem.h
1 /*
2  *  scst_mem.h
3  *
4  *  Copyright (C) 2006 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
5  *  Copyright (C) 2007 - 2009 ID7 Ltd.
6  *
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU General Public License
9  *  as published by the Free Software Foundation, version 2
10  *  of the License.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  */
17
18 #include <linux/scatterlist.h>
19 #include <linux/workqueue.h>
20 #include <linux/seq_file.h>
21
22 #define SGV_POOL_ELEMENTS       11
23
24 /*
25  * sg_num is indexed by the page number, pg_count is indexed by the sg number.
26  * Made in one entry to simplify the code (eg all sizeof(*) parts) and save
27  * some CPU cache for non-clustered case.
28  */
29 struct trans_tbl_ent {
30         unsigned short sg_num;
31         unsigned short pg_count;
32 };
33
34 struct sgv_pool_obj {
35         int cache_num;
36         int pages;
37
38         /* jiffies, protected by sgv_pool_lock */
39         unsigned long time_stamp;
40
41         struct list_head recycling_list_entry;
42         struct list_head sorted_recycling_list_entry;
43
44         struct sgv_pool *owner_pool;
45         int orig_sg;
46         int orig_length;
47         int sg_count;
48         void *allocator_priv;
49         struct trans_tbl_ent *trans_tbl;
50         struct scatterlist *sg_entries;
51         struct scatterlist sg_entries_data[0];
52 };
53
54 struct sgv_pool_cache_acc {
55         atomic_t total_alloc, hit_alloc;
56         atomic_t merged;
57 };
58
59 struct sgv_pool_alloc_fns {
60         struct page *(*alloc_pages_fn)(struct scatterlist *sg, gfp_t gfp_mask,
61                 void *priv);
62         void (*free_pages_fn)(struct scatterlist *sg, int sg_count,
63                 void *priv);
64 };
65
66 struct sgv_pool {
67         enum sgv_clustering_types clustering_type;
68         int single_alloc_pages;
69         int max_cached_pages;
70
71         struct sgv_pool_alloc_fns alloc_fns;
72
73         /* <=4K, <=8, <=16, <=32, <=64, <=128, <=256, <=512, <=1024, <=2048 */
74         struct kmem_cache *caches[SGV_POOL_ELEMENTS];
75
76         spinlock_t sgv_pool_lock; /* outer lock for sgv_pools_lock! */
77
78         int purge_interval;
79
80         /* Protected by sgv_pool_lock */
81         unsigned int purge_work_scheduled:1;
82
83         /* Protected by sgv_pool_lock */
84         struct list_head sorted_recycling_list;
85
86         int inactive_cached_pages; /* protected by sgv_pool_lock */
87
88         /* Protected by sgv_pool_lock */
89         struct list_head recycling_lists[SGV_POOL_ELEMENTS];
90
91         int cached_pages, cached_entries; /* protected by sgv_pool_lock */
92
93         struct sgv_pool_cache_acc cache_acc[SGV_POOL_ELEMENTS];
94
95 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20))
96         struct delayed_work sgv_purge_work;
97 #else
98         struct work_struct sgv_purge_work;
99 #endif
100
101         struct list_head sgv_active_pools_list_entry;
102
103         atomic_t big_alloc, big_pages, big_merged;
104         atomic_t other_alloc, other_pages, other_merged;
105
106         atomic_t sgv_pool_ref;
107
108         int max_caches;
109
110         /* SCST_MAX_NAME + few more bytes to match scst_user expectations */
111         char cache_names[SGV_POOL_ELEMENTS][SCST_MAX_NAME + 10];
112         char name[SCST_MAX_NAME + 10];
113
114         struct mm_struct *owner_mm;
115
116         struct list_head sgv_pools_list_entry;
117 };
118
119 int sgv_pool_init(struct sgv_pool *pool, const char *name,
120         enum sgv_clustering_types clustering_type, int single_alloc_pages,
121         int purge_interval);
122 void sgv_pool_deinit(struct sgv_pool *pool);
123
124 static inline struct scatterlist *sgv_pool_sg(struct sgv_pool_obj *obj)
125 {
126         return obj->sg_entries;
127 }
128
129 extern int scst_sgv_pools_init(unsigned long mem_hwmark,
130                                unsigned long mem_lwmark);
131 extern void scst_sgv_pools_deinit(void);
132 extern int sgv_procinfo_show(struct seq_file *seq, void *v);
133
134 void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev);
135 void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev);
136 void scst_sgv_pool_use_dma(struct scst_tgt_dev *tgt_dev);