@@ -80,23 +80,39 @@ static u64 zswap_duplicate_entry;
80
80
static bool zswap_enabled ;
81
81
module_param_named (enabled , zswap_enabled , bool , 0644 );
82
82
83
- /* Compressor to be used by zswap (fixed at boot for now) */
83
+ /* Crypto compressor to use */
84
84
#define ZSWAP_COMPRESSOR_DEFAULT "lzo"
85
- static char * zswap_compressor = ZSWAP_COMPRESSOR_DEFAULT ;
86
- module_param_named (compressor , zswap_compressor , charp , 0444 );
87
-
88
- /* The maximum percentage of memory that the compressed pool can occupy */
89
- static unsigned int zswap_max_pool_percent = 20 ;
90
- module_param_named (max_pool_percent ,
91
- zswap_max_pool_percent , uint , 0644 );
85
+ static char zswap_compressor [CRYPTO_MAX_ALG_NAME ] = ZSWAP_COMPRESSOR_DEFAULT ;
86
+ static struct kparam_string zswap_compressor_kparam = {
87
+ .string = zswap_compressor ,
88
+ .maxlen = sizeof (zswap_compressor ),
89
+ };
90
+ static int zswap_compressor_param_set (const char * ,
91
+ const struct kernel_param * );
92
+ static struct kernel_param_ops zswap_compressor_param_ops = {
93
+ .set = zswap_compressor_param_set ,
94
+ .get = param_get_string ,
95
+ };
96
+ module_param_cb (compressor , & zswap_compressor_param_ops ,
97
+ & zswap_compressor_kparam , 0644 );
92
98
93
- /* Compressed storage to use */
99
+ /* Compressed storage zpool to use */
94
100
#define ZSWAP_ZPOOL_DEFAULT "zbud"
95
- static char * zswap_zpool_type = ZSWAP_ZPOOL_DEFAULT ;
96
- module_param_named (zpool , zswap_zpool_type , charp , 0444 );
101
+ static char zswap_zpool_type [32 /* arbitrary */ ] = ZSWAP_ZPOOL_DEFAULT ;
102
+ static struct kparam_string zswap_zpool_kparam = {
103
+ .string = zswap_zpool_type ,
104
+ .maxlen = sizeof (zswap_zpool_type ),
105
+ };
106
+ static int zswap_zpool_param_set (const char * , const struct kernel_param * );
107
+ static struct kernel_param_ops zswap_zpool_param_ops = {
108
+ .set = zswap_zpool_param_set ,
109
+ .get = param_get_string ,
110
+ };
111
+ module_param_cb (zpool , & zswap_zpool_param_ops , & zswap_zpool_kparam , 0644 );
97
112
98
- /* zpool is shared by all of zswap backend */
99
- static struct zpool * zswap_pool ;
113
+ /* The maximum percentage of memory that the compressed pool can occupy */
114
+ static unsigned int zswap_max_pool_percent = 20 ;
115
+ module_param_named (max_pool_percent , zswap_max_pool_percent , uint , 0644 );
100
116
101
117
/*********************************
102
118
* data structures
@@ -161,6 +177,9 @@ static LIST_HEAD(zswap_pools);
161
177
/* protects zswap_pools list modification */
162
178
static DEFINE_SPINLOCK (zswap_pools_lock );
163
179
180
+ /* used by param callback function */
181
+ static bool zswap_init_started ;
182
+
164
183
/*********************************
165
184
* helpers and fwd declarations
166
185
**********************************/
@@ -661,6 +680,101 @@ static void zswap_pool_put(struct zswap_pool *pool)
661
680
kref_put (& pool -> kref , __zswap_pool_empty );
662
681
}
663
682
683
+ /*********************************
684
+ * param callbacks
685
+ **********************************/
686
+
687
+ static int __zswap_param_set (const char * val , const struct kernel_param * kp ,
688
+ char * type , char * compressor )
689
+ {
690
+ struct zswap_pool * pool , * put_pool = NULL ;
691
+ char str [kp -> str -> maxlen ], * s ;
692
+ int ret ;
693
+
694
+ /*
695
+ * kp is either zswap_zpool_kparam or zswap_compressor_kparam, defined
696
+ * at the top of this file, so maxlen is CRYPTO_MAX_ALG_NAME (64) or
697
+ * 32 (arbitrary).
698
+ */
699
+ strlcpy (str , val , kp -> str -> maxlen );
700
+ s = strim (str );
701
+
702
+ /* if this is load-time (pre-init) param setting,
703
+ * don't create a pool; that's done during init.
704
+ */
705
+ if (!zswap_init_started )
706
+ return param_set_copystring (s , kp );
707
+
708
+ /* no change required */
709
+ if (!strncmp (kp -> str -> string , s , kp -> str -> maxlen ))
710
+ return 0 ;
711
+
712
+ if (!type ) {
713
+ type = s ;
714
+ if (!zpool_has_pool (type )) {
715
+ pr_err ("zpool %s not available\n" , type );
716
+ return - ENOENT ;
717
+ }
718
+ } else if (!compressor ) {
719
+ compressor = s ;
720
+ if (!crypto_has_comp (compressor , 0 , 0 )) {
721
+ pr_err ("compressor %s not available\n" , compressor );
722
+ return - ENOENT ;
723
+ }
724
+ }
725
+
726
+ spin_lock (& zswap_pools_lock );
727
+
728
+ pool = zswap_pool_find_get (type , compressor );
729
+ if (pool ) {
730
+ zswap_pool_debug ("using existing" , pool );
731
+ list_del_rcu (& pool -> list );
732
+ } else {
733
+ spin_unlock (& zswap_pools_lock );
734
+ pool = zswap_pool_create (type , compressor );
735
+ spin_lock (& zswap_pools_lock );
736
+ }
737
+
738
+ if (pool )
739
+ ret = param_set_copystring (s , kp );
740
+ else
741
+ ret = - EINVAL ;
742
+
743
+ if (!ret ) {
744
+ put_pool = zswap_pool_current ();
745
+ list_add_rcu (& pool -> list , & zswap_pools );
746
+ } else if (pool ) {
747
+ /* add the possibly pre-existing pool to the end of the pools
748
+ * list; if it's new (and empty) then it'll be removed and
749
+ * destroyed by the put after we drop the lock
750
+ */
751
+ list_add_tail_rcu (& pool -> list , & zswap_pools );
752
+ put_pool = pool ;
753
+ }
754
+
755
+ spin_unlock (& zswap_pools_lock );
756
+
757
+ /* drop the ref from either the old current pool,
758
+ * or the new pool we failed to add
759
+ */
760
+ if (put_pool )
761
+ zswap_pool_put (put_pool );
762
+
763
+ return ret ;
764
+ }
765
+
766
+ static int zswap_compressor_param_set (const char * val ,
767
+ const struct kernel_param * kp )
768
+ {
769
+ return __zswap_param_set (val , kp , zswap_zpool_type , NULL );
770
+ }
771
+
772
+ static int zswap_zpool_param_set (const char * val ,
773
+ const struct kernel_param * kp )
774
+ {
775
+ return __zswap_param_set (val , kp , NULL , zswap_compressor );
776
+ }
777
+
664
778
/*********************************
665
779
* writeback code
666
780
**********************************/
@@ -1114,6 +1228,8 @@ static int __init init_zswap(void)
1114
1228
{
1115
1229
struct zswap_pool * pool ;
1116
1230
1231
+ zswap_init_started = true;
1232
+
1117
1233
if (zswap_entry_cache_create ()) {
1118
1234
pr_err ("entry cache creation failed\n" );
1119
1235
goto cache_fail ;
0 commit comments