@@ -1068,69 +1068,103 @@ bio_led_manage(struct bio_xs_context *xs_ctxt, char *tr_addr, uuid_t dev_uuid, u
10681068 duration );
10691069}
10701070
1071+ static void
1072+ bdev_event_cb (enum spdk_bdev_event_type type , struct spdk_bdev * bdev , void * event_ctx )
1073+ {
1074+ D_ERROR ("Unsupported bdev event: type %d\n" , type );
1075+ }
1076+
1077+ struct power_mgmt_context_t {
1078+ struct spdk_bdev_desc * bdev_desc ;
1079+ struct spdk_io_channel * bdev_io_channel ;
1080+ const char * bdev_name ;
1081+ };
1082+
10711083static void
10721084set_power_mgmt_completion (struct spdk_bdev_io * bdev_io , bool success , void * cb_arg )
10731085{
1074- struct bio_bdev * d_bdev = cb_arg ;
1086+ struct power_mgmt_context_t * pm_ctx = cb_arg ;
10751087 int sc ;
10761088 int sct ;
10771089 uint32_t cdw0 ;
10781090
10791091 spdk_bdev_io_get_nvme_status (bdev_io , & cdw0 , & sct , & sc );
10801092 if (sc ) {
10811093 D_ERROR ("Set power management failed for device %s, NVMe status code/type: %d/%d\n" ,
1082- d_bdev -> bb_name , sc , sct );
1094+ pm_ctx -> bdev_name , sc , sct );
10831095 } else {
1084- D_INFO ("Power management value set on device %s\n" , d_bdev -> bb_name );
1096+ D_INFO ("Power management value set on device %s\n" , pm_ctx -> bdev_name );
10851097 }
10861098
10871099 spdk_bdev_free_io (bdev_io );
1100+ spdk_put_io_channel (pm_ctx -> bdev_io_channel );
1101+ spdk_bdev_close (pm_ctx -> bdev_desc );
10881102}
10891103
10901104int
1091- bio_set_power_mgmt (struct bio_bdev * d_bdev , struct spdk_io_channel * channel )
1105+ bio_set_power_mgmt (const char * bdev_name )
10921106{
1107+ struct power_mgmt_context_t pm_ctx = {};
10931108 struct spdk_bdev * bdev ;
10941109 struct spdk_nvme_cmd cmd ;
1095- int rc ;
1110+ int rc = 0 ;
10961111
10971112 /* If default has not been overwritten, skip setting the value */
10981113 if (bio_spdk_power_mgmt_val == UINT32_MAX )
1099- return 0 ;
1114+ goto out ;
11001115
1101- D_ASSERT (d_bdev != NULL );
1102- D_ASSERT (d_bdev -> bb_desc != NULL );
1103- D_ASSERT (channel != NULL );
1116+ D_ASSERT (bdev_name != NULL );
1117+ pm_ctx .bdev_name = bdev_name ;
1118+
1119+ /* Writable descriptor required for applying power management settings */
1120+ rc = spdk_bdev_open_ext (bdev_name , true, bdev_event_cb , NULL , & pm_ctx .bdev_desc );
1121+ if (rc != 0 ) {
1122+ D_ERROR ("Failed to open bdev %s, %d\n" , bdev_name , rc );
1123+ rc = daos_errno2der (- rc );
1124+ goto out ;
1125+ }
11041126
1105- bdev = spdk_bdev_desc_get_bdev (d_bdev -> bb_desc );
1127+ bdev = spdk_bdev_desc_get_bdev (pm_ctx . bdev_desc );
11061128 if (bdev == NULL ) {
1107- D_ERROR ("No bdev associated with device descriptor\n" );
1108- return - DER_INVAL ;
1129+ D_ERROR ("No bdev associated with device descriptor for %s\n" , bdev_name );
1130+ rc = - DER_INVAL ;
1131+ goto out_bdev ;
11091132 }
11101133
1134+ pm_ctx .bdev_io_channel = spdk_bdev_get_io_channel (pm_ctx .bdev_desc );
1135+ D_ASSERT (pm_ctx .bdev_io_channel != NULL );
1136+
11111137 if (get_bdev_type (bdev ) != BDEV_CLASS_NVME ) {
1112- D_DEBUG (DB_MGMT , "Device %s is not NVMe, skipping power management\n" ,
1113- d_bdev -> bb_name ) ;
1114- return - DER_NOTSUPPORTED ;
1138+ D_DEBUG (DB_MGMT , "Device %s is not NVMe, skipping power management\n" , bdev_name );
1139+ rc = - DER_NOTSUPPORTED ;
1140+ goto out_chan ;
11151141 }
11161142
11171143 if (!spdk_bdev_io_type_supported (bdev , SPDK_BDEV_IO_TYPE_NVME_ADMIN )) {
1118- D_ERROR ("Bdev NVMe admin passthru not supported for %s\n" , d_bdev -> bb_name );
1119- return - DER_NOTSUPPORTED ;
1144+ D_ERROR ("Bdev NVMe admin passthru not supported for %s\n" , bdev_name );
1145+ rc = - DER_NOTSUPPORTED ;
1146+ goto out_chan ;
11201147 }
11211148
11221149 memset (& cmd , 0 , sizeof (cmd ));
11231150 cmd .opc = SPDK_NVME_OPC_SET_FEATURES ;
11241151 cmd .cdw10 = SPDK_NVME_FEAT_POWER_MANAGEMENT ;
11251152 cmd .cdw11 = bio_spdk_power_mgmt_val ;
11261153
1127- rc = spdk_bdev_nvme_admin_passthru (d_bdev -> bb_desc , channel , & cmd , NULL , 0 ,
1128- set_power_mgmt_completion , d_bdev );
1129- if (rc ) {
1130- D_ERROR ("Failed to submit power management command for %s, rc:%d\n" ,
1131- d_bdev -> bb_name , rc );
1132- return daos_errno2der ( - rc ) ;
1154+ rc = spdk_bdev_nvme_admin_passthru (pm_ctx . bdev_desc , pm_ctx . bdev_io_channel , & cmd , NULL , 0 ,
1155+ set_power_mgmt_completion , & pm_ctx );
1156+ if (rc != 0 ) {
1157+ D_ERROR ("Failed to submit power management command for %s, rc:%d\n" , bdev_name , rc );
1158+ rc = daos_errno2der ( - rc );
1159+ goto out_chan ;
11331160 }
11341161
11351162 return 0 ;
1163+
1164+ out_chan :
1165+ spdk_put_io_channel (pm_ctx .bdev_io_channel );
1166+ out_bdev :
1167+ spdk_bdev_close (pm_ctx .bdev_desc );
1168+ out :
1169+ return rc ;
11361170}
0 commit comments