@@ -60,6 +60,7 @@ static const char *power_limit_feat = "power limit feature";
6060static const char * power_thresh_feat = "power threshold feature" ;
6161static const char * power_meas_feat = "power measurement feature" ;
6262static const char * err_recovery_feat = "error recovery feature" ;
63+ static const char * num_queues_feat = "number of queues feature" ;
6364
6465static int feat_get_nsid (struct nvme_transport_handle * hdl , __u32 nsid ,
6566 const __u8 fid , __u32 cdw11 , __u8 sel , __u8 uidx ,
@@ -916,3 +917,85 @@ static int feat_err_recovery(int argc, char **argv, struct command *acmd,
916917
917918 return err ;
918919}
920+
921+ static int num_queues_set (struct nvme_transport_handle * hdl , const __u8 fid ,
922+ __u16 nsqr , __u16 ncqr , bool sv ,
923+ struct argconfig_commandline_options * opts )
924+ {
925+ enum nvme_get_features_sel sel = NVME_GET_FEATURES_SEL_CURRENT ;
926+ __u32 cdw11 = NVME_SET (nsqr , FEAT_NRQS_NSQR ) |
927+ NVME_SET (ncqr , FEAT_NRQS_NCQR );
928+ struct nvme_passthru_cmd cmd ;
929+ __u64 result ;
930+ int err ;
931+
932+ if (sv )
933+ sel = NVME_GET_FEATURES_SEL_SAVED ;
934+
935+ nvme_init_get_features_num_queues (& cmd , sel );
936+ err = nvme_submit_admin_passthru (hdl , & cmd );
937+ if (!err ) {
938+ nvme_feature_decode_number_of_queues (cmd .result , & nsqr , & ncqr );
939+ if (!argconfig_parse_seen (opts , "nsqr" ))
940+ cdw11 |= NVME_SET (nsqr , FEAT_NRQS_NSQR );
941+ if (!argconfig_parse_seen (opts , "ncqr" ))
942+ cdw11 |= NVME_SET (ncqr , FEAT_NRQS_NSQR );
943+ }
944+
945+ err = nvme_set_features (hdl , 0 , fid , sv , cdw11 , 0 , 0 , 0 , 0 , NULL , 0 ,
946+ & result );
947+
948+ nvme_show_init ();
949+
950+ if (err > 0 ) {
951+ nvme_show_status (err );
952+ } else if (err < 0 ) {
953+ nvme_show_perror ("Set %s" , num_queues_feat );
954+ } else {
955+ nvme_show_result ("Set %s: 0x%04x (%s)" , num_queues_feat ,
956+ cdw11 , sv ? "Save" : "Not save" );
957+ nvme_feature_show_fields (fid , cdw11 , NULL );
958+ }
959+
960+ nvme_show_finish ();
961+
962+ return err ;
963+ }
964+
965+ static int feat_num_queues (int argc , char * * argv , struct command * acmd ,
966+ struct plugin * plugin )
967+ {
968+ _cleanup_nvme_transport_handle_ struct nvme_transport_handle * hdl =
969+ NULL ;
970+ _cleanup_nvme_global_ctx_ struct nvme_global_ctx * ctx = NULL ;
971+
972+ const char * ncqr = "number of I/O completion queues requested" ;
973+ const char * nsqr = "number of I/O submission queues requested" ;
974+ const __u8 fid = NVME_FEAT_FID_NUM_QUEUES ;
975+ int err ;
976+
977+ struct config {
978+ __u16 nsqr ;
979+ __u16 ncqr ;
980+ __u8 sel ;
981+ };
982+
983+ struct config cfg = { 0 };
984+
985+ FEAT_ARGS (opts ,
986+ OPT_SHRT ("nsqr" , 'n' , & cfg .nsqr , nsqr ),
987+ OPT_SHRT ("ncqr" , 'c' , & cfg .ncqr , ncqr ));
988+
989+ err = parse_and_open (& ctx , & hdl , argc , argv , NUM_QUEUES_DESC , opts );
990+ if (err )
991+ return err ;
992+
993+ if (argconfig_parse_seen (opts , "nsqr" ) ||
994+ argconfig_parse_seen (opts , "ncqr" ))
995+ err = num_queues_set (hdl , fid , cfg .nsqr , cfg .ncqr ,
996+ argconfig_parse_seen (opts , "save" ), opts );
997+ else
998+ err = feat_get (hdl , fid , 0 , cfg .sel , 0 , num_queues_feat );
999+
1000+ return err ;
1001+ }
0 commit comments