Update to work on 2.6.20 + minor fix
[mirror/scst/.git] / scst / src / scst_mem.h
1 /*
2  *  scst_sgv_pool.h
3  *  
4  *  Copyright (C) 2006 Vladislav Bolkhovitin <vst@vlnb.net>
5  *  
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  as published by the Free Software Foundation, version 2
9  *  of the License.
10  * 
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  *  GNU General Public License for more details.
15  */
16
17 #include <asm/scatterlist.h>
18
19 #define SGV_POOL_ELEMENTS       11
20
21 #if defined(DEBUG) && defined(CONFIG_DEBUG_SLAB)
22 #define SCST_SLAB_FLAGS ( SLAB_RED_ZONE | SLAB_POISON )
23 #else
24 #define SCST_SLAB_FLAGS 0L
25 #endif
26
27 /* 
28  * sg_num is indexed by the page number, pg_count is indexed by the sg number.
29  * Made in one entry to simplify the code (eg all sizeof(*) parts) and save
30  * the CPU cache for non-clustered case.
31  */
32 struct trans_tbl_ent {
33         unsigned short sg_num;
34         unsigned short pg_count;
35 };
36
37 struct sgv_pool_obj
38 {
39         struct kmem_cache *owner_cache;
40         int eorder;
41         int orig_sg;
42         int orig_length;
43         int sg_count;
44         struct scatterlist *entries;
45         struct trans_tbl_ent trans_tbl[0];
46 };
47
48 struct sgv_pool_acc
49 {
50         atomic_t total_alloc, hit_alloc;
51 };
52
53 struct sgv_pool
54 {
55         struct sgv_pool_acc acc;
56         struct sgv_pool_acc cache_acc[SGV_POOL_ELEMENTS];
57         unsigned int clustered:1;
58         /* 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 */
59         struct kmem_cache *caches[SGV_POOL_ELEMENTS];
60         char cache_names[SGV_POOL_ELEMENTS][25];
61 };
62
63 struct scst_sgv_pools
64 {
65         struct sgv_pool norm_clust, norm;
66         struct sgv_pool dma;
67 #ifdef SCST_HIGHMEM
68         struct sgv_pool highmem;
69 #endif
70 };
71
72 extern atomic_t sgv_big_total_alloc;
73 extern atomic_t sgv_other_total_alloc;
74
75 extern struct sgv_pool *sgv_pool_create(const char *name, int clustered);
76 extern void sgv_pool_destroy(struct sgv_pool *pool);
77
78 extern int sgv_pool_init(struct sgv_pool *pool, const char *name, 
79         int clustered);
80 extern void sgv_pool_deinit(struct sgv_pool *pool);
81
82 extern struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, int size,
83         unsigned long gfp_mask, int atomic, int *count,
84         struct sgv_pool_obj **sgv);
85 static inline void sgv_pool_free(struct sgv_pool_obj *sgv)
86 {
87         TRACE_MEM("Freeing sgv_obj %p", sgv);
88         sgv->entries[sgv->orig_sg].length = sgv->orig_length;
89         kmem_cache_free(sgv->owner_cache, sgv);
90 }
91
92 static inline struct scatterlist *sgv_pool_sg(struct sgv_pool_obj *obj)
93 {
94         return obj->entries;
95 }
96
97 extern int scst_sgv_pools_init(struct scst_sgv_pools *pools);
98 extern void scst_sgv_pools_deinit(struct scst_sgv_pools *pools);