4 * Copyright (C) 2006 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
5 * Copyright (C) 2007 Krzysztof Blaszkowski <kb@sysmikro.com.pl>
6 * Copyright (C) 2007 - 2009 ID7 Ltd.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation, version 2
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #include <linux/scatterlist.h>
20 #include <linux/workqueue.h>
21 #include <linux/seq_file.h>
23 #define SGV_POOL_ELEMENTS 11
26 * sg_num is indexed by the page number, pg_count is indexed by the sg number.
27 * Made in one entry to simplify the code (eg all sizeof(*) parts) and save
28 * some CPU cache for non-clustered case.
30 struct trans_tbl_ent {
31 unsigned short sg_num;
32 unsigned short pg_count;
36 /* if <0 - pages, >0 - order */
40 /* jiffies, protected by pool_mgr_lock */
41 unsigned long time_stamp;
42 struct list_head recycling_list_entry;
43 struct list_head sorted_recycling_list_entry;
46 struct sgv_pool *owner_pool;
51 struct trans_tbl_ent *trans_tbl;
52 struct scatterlist *sg_entries;
53 struct scatterlist sg_entries_data[0];
57 u32 cached_pages, cached_entries;
58 atomic_t big_alloc, other_alloc;
59 atomic_t big_pages, other_pages;
60 atomic_t big_merged, other_merged;
63 struct sgv_pool_cache_acc {
64 atomic_t total_alloc, hit_alloc;
68 struct sgv_pool_alloc_fns {
69 struct page *(*alloc_pages_fn)(struct scatterlist *sg, gfp_t gfp_mask,
71 void (*free_pages_fn)(struct scatterlist *sg, int sg_count,
76 enum sgv_clustering_types clustering_type;
77 struct sgv_pool_alloc_fns alloc_fns;
78 /* 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 */
79 struct kmem_cache *caches[SGV_POOL_ELEMENTS];
81 /* protected by pool_mgr_lock */
82 struct list_head recycling_lists[SGV_POOL_ELEMENTS];
84 struct sgv_pool_acc acc;
85 struct sgv_pool_cache_acc cache_acc[SGV_POOL_ELEMENTS];
87 /* SCST_MAX_NAME + few more bytes to match scst_user expectations */
88 char cache_names[SGV_POOL_ELEMENTS][SCST_MAX_NAME + 10];
89 char name[SCST_MAX_NAME + 10];
90 struct list_head sgv_pool_list_entry;
93 struct scst_sgv_pools_manager {
95 struct sgv_pool norm_clust, norm;
100 spinlock_t pool_mgr_lock;
101 /* protected by pool_mgr_lock */
102 struct list_head sorted_recycling_list;
103 /* protected by pool_mgr_lock */
104 unsigned pitbool_running:1;
106 struct sgv_mem_throttling {
107 u32 inactive_pages_total;
108 u32 active_pages_total;
111 * compared against inactive_pages_total +
115 /* compared against inactive_pages_total only */
118 u32 releases_on_hiwmk;
120 } throttle; /* protected by pool_mgr_lock */
122 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23))
123 struct shrinker *sgv_shrinker;
125 struct shrinker sgv_shrinker;
128 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20))
129 struct delayed_work apit_pool;
131 struct work_struct apit_pool;
135 int sgv_max_local_order, sgv_max_trans_order;
137 atomic_t sgv_other_total_alloc;
138 struct mutex scst_sgv_pool_mutex;
139 struct list_head scst_sgv_pool_list;
142 int sgv_pool_init(struct sgv_pool *pool, const char *name,
143 enum sgv_clustering_types clustering_type);
144 void sgv_pool_deinit(struct sgv_pool *pool);
146 static inline struct scatterlist *sgv_pool_sg(struct sgv_pool_obj *obj)
148 return obj->sg_entries;
151 extern int scst_sgv_pools_init(unsigned long mem_hwmark,
152 unsigned long mem_lwmark);
153 extern void scst_sgv_pools_deinit(void);
154 extern int sgv_pool_procinfo_show(struct seq_file *seq, void *v);
156 void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev);
157 void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev);
158 void scst_sgv_pool_use_dma(struct scst_tgt_dev *tgt_dev);