15
15
#include <linux/dma-mapping.h>
16
16
#include <linux/workqueue.h>
17
17
#include <linux/libnvdimm.h>
18
+ #include <linux/genalloc.h>
18
19
#include <linux/vmalloc.h>
19
20
#include <linux/device.h>
20
21
#include <linux/module.h>
@@ -215,6 +216,8 @@ struct nfit_test {
215
216
216
217
static struct workqueue_struct * nfit_wq ;
217
218
219
+ static struct gen_pool * nfit_pool ;
220
+
218
221
static struct nfit_test * to_nfit_test (struct device * dev )
219
222
{
220
223
struct platform_device * pdev = to_platform_device (dev );
@@ -1132,6 +1135,9 @@ static void release_nfit_res(void *data)
1132
1135
list_del (& nfit_res -> list );
1133
1136
spin_unlock (& nfit_test_lock );
1134
1137
1138
+ if (resource_size (& nfit_res -> res ) >= DIMM_SIZE )
1139
+ gen_pool_free (nfit_pool , nfit_res -> res .start ,
1140
+ resource_size (& nfit_res -> res ));
1135
1141
vfree (nfit_res -> buf );
1136
1142
kfree (nfit_res );
1137
1143
}
@@ -1144,7 +1150,7 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
1144
1150
GFP_KERNEL );
1145
1151
int rc ;
1146
1152
1147
- if (!buf || !nfit_res )
1153
+ if (!buf || !nfit_res || ! * dma )
1148
1154
goto err ;
1149
1155
rc = devm_add_action (dev , release_nfit_res , nfit_res );
1150
1156
if (rc )
@@ -1164,6 +1170,8 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
1164
1170
1165
1171
return nfit_res -> buf ;
1166
1172
err :
1173
+ if (* dma && size >= DIMM_SIZE )
1174
+ gen_pool_free (nfit_pool , * dma , size );
1167
1175
if (buf )
1168
1176
vfree (buf );
1169
1177
kfree (nfit_res );
@@ -1172,9 +1180,16 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
1172
1180
1173
1181
static void * test_alloc (struct nfit_test * t , size_t size , dma_addr_t * dma )
1174
1182
{
1183
+ struct genpool_data_align data = {
1184
+ .align = SZ_128M ,
1185
+ };
1175
1186
void * buf = vmalloc (size );
1176
1187
1177
- * dma = (unsigned long ) buf ;
1188
+ if (size >= DIMM_SIZE )
1189
+ * dma = gen_pool_alloc_algo (nfit_pool , size ,
1190
+ gen_pool_first_fit_align , & data );
1191
+ else
1192
+ * dma = (unsigned long ) buf ;
1178
1193
return __test_alloc (t , size , dma , buf );
1179
1194
}
1180
1195
@@ -2839,6 +2854,17 @@ static __init int nfit_test_init(void)
2839
2854
goto err_register ;
2840
2855
}
2841
2856
2857
+ nfit_pool = gen_pool_create (ilog2 (SZ_4M ), NUMA_NO_NODE );
2858
+ if (!nfit_pool ) {
2859
+ rc = - ENOMEM ;
2860
+ goto err_register ;
2861
+ }
2862
+
2863
+ if (gen_pool_add (nfit_pool , SZ_4G , SZ_4G , NUMA_NO_NODE )) {
2864
+ rc = - ENOMEM ;
2865
+ goto err_register ;
2866
+ }
2867
+
2842
2868
for (i = 0 ; i < NUM_NFITS ; i ++ ) {
2843
2869
struct nfit_test * nfit_test ;
2844
2870
struct platform_device * pdev ;
@@ -2894,6 +2920,9 @@ static __init int nfit_test_init(void)
2894
2920
return 0 ;
2895
2921
2896
2922
err_register :
2923
+ if (nfit_pool )
2924
+ gen_pool_destroy (nfit_pool );
2925
+
2897
2926
destroy_workqueue (nfit_wq );
2898
2927
for (i = 0 ; i < NUM_NFITS ; i ++ )
2899
2928
if (instances [i ])
@@ -2917,6 +2946,8 @@ static __exit void nfit_test_exit(void)
2917
2946
platform_driver_unregister (& nfit_test_driver );
2918
2947
nfit_test_teardown ();
2919
2948
2949
+ gen_pool_destroy (nfit_pool );
2950
+
2920
2951
for (i = 0 ; i < NUM_NFITS ; i ++ )
2921
2952
put_device (& instances [i ]-> pdev .dev );
2922
2953
class_destroy (nfit_test_dimm );
0 commit comments