@@ -108,7 +108,7 @@ struct iv_tcw_private {
108108 * Crypt: maps a linear range of a block device
109109 * and encrypts / decrypts at the same time.
110110 */
111- enum flags { DM_CRYPT_SUSPENDED , DM_CRYPT_KEY_VALID };
111+ enum flags { DM_CRYPT_SUSPENDED , DM_CRYPT_KEY_VALID , DM_CRYPT_SAME_CPU };
112112
113113/*
114114 * The fields in here must be read only after initialization.
@@ -1688,7 +1688,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
16881688 char dummy ;
16891689
16901690 static struct dm_arg _args [] = {
1691- {0 , 1 , "Invalid number of feature args" },
1691+ {0 , 2 , "Invalid number of feature args" },
16921692 };
16931693
16941694 if (argc < 5 ) {
@@ -1788,15 +1788,23 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
17881788 if (ret )
17891789 goto bad ;
17901790
1791- opt_string = dm_shift_arg (& as );
1791+ while (opt_params -- ) {
1792+ opt_string = dm_shift_arg (& as );
1793+ if (!opt_string ) {
1794+ ti -> error = "Not enough feature arguments" ;
1795+ goto bad ;
1796+ }
17921797
1793- if (opt_params == 1 && opt_string &&
1794- !strcasecmp (opt_string , "allow_discards" ))
1795- ti -> num_discard_bios = 1 ;
1796- else if (opt_params ) {
1797- ret = - EINVAL ;
1798- ti -> error = "Invalid feature arguments" ;
1799- goto bad ;
1798+ if (!strcasecmp (opt_string , "allow_discards" ))
1799+ ti -> num_discard_bios = 1 ;
1800+
1801+ else if (!strcasecmp (opt_string , "same_cpu_crypt" ))
1802+ set_bit (DM_CRYPT_SAME_CPU , & cc -> flags );
1803+
1804+ else {
1805+ ti -> error = "Invalid feature arguments" ;
1806+ goto bad ;
1807+ }
18001808 }
18011809 }
18021810
@@ -1807,8 +1815,11 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
18071815 goto bad ;
18081816 }
18091817
1810- cc -> crypt_queue = alloc_workqueue ("kcryptd" ,
1811- WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM , 1 );
1818+ if (test_bit (DM_CRYPT_SAME_CPU , & cc -> flags ))
1819+ cc -> crypt_queue = alloc_workqueue ("kcryptd" , WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM , 1 );
1820+ else
1821+ cc -> crypt_queue = alloc_workqueue ("kcryptd" , WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND ,
1822+ num_online_cpus ());
18121823 if (!cc -> crypt_queue ) {
18131824 ti -> error = "Couldn't create kcryptd queue" ;
18141825 goto bad ;
@@ -1860,6 +1871,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
18601871{
18611872 struct crypt_config * cc = ti -> private ;
18621873 unsigned i , sz = 0 ;
1874+ int num_feature_args = 0 ;
18631875
18641876 switch (type ) {
18651877 case STATUSTYPE_INFO :
@@ -1878,8 +1890,15 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
18781890 DMEMIT (" %llu %s %llu" , (unsigned long long )cc -> iv_offset ,
18791891 cc -> dev -> name , (unsigned long long )cc -> start );
18801892
1881- if (ti -> num_discard_bios )
1882- DMEMIT (" 1 allow_discards" );
1893+ num_feature_args += !!ti -> num_discard_bios ;
1894+ num_feature_args += test_bit (DM_CRYPT_SAME_CPU , & cc -> flags );
1895+ if (num_feature_args ) {
1896+ DMEMIT (" %d" , num_feature_args );
1897+ if (ti -> num_discard_bios )
1898+ DMEMIT (" allow_discards" );
1899+ if (test_bit (DM_CRYPT_SAME_CPU , & cc -> flags ))
1900+ DMEMIT (" same_cpu_crypt" );
1901+ }
18831902
18841903 break ;
18851904 }
@@ -1976,7 +1995,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
19761995
19771996static struct target_type crypt_target = {
19781997 .name = "crypt" ,
1979- .version = {1 , 13 , 0 },
1998+ .version = {1 , 14 , 0 },
19801999 .module = THIS_MODULE ,
19812000 .ctr = crypt_ctr ,
19822001 .dtr = crypt_dtr ,
0 commit comments