@@ -1370,8 +1370,8 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
13701370 u32 effects = 0 ;
13711371
13721372 if (ns ) {
1373- if (ctrl -> effects )
1374- effects = le32_to_cpu (ctrl -> effects -> iocs [opcode ]);
1373+ if (ns -> head -> effects )
1374+ effects = le32_to_cpu (ns -> head -> effects -> iocs [opcode ]);
13751375 if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC ))
13761376 dev_warn (ctrl -> device ,
13771377 "IO command:%02x has unhandled effects:%08x\n" ,
@@ -2851,7 +2851,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
28512851 return ret ;
28522852}
28532853
2854- int nvme_get_log (struct nvme_ctrl * ctrl , u32 nsid , u8 log_page , u8 lsp ,
2854+ int nvme_get_log (struct nvme_ctrl * ctrl , u32 nsid , u8 log_page , u8 lsp , u8 csi ,
28552855 void * log , size_t size , u64 offset )
28562856{
28572857 struct nvme_command c = { };
@@ -2865,27 +2865,55 @@ int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp,
28652865 c .get_log_page .numdu = cpu_to_le16 (dwlen >> 16 );
28662866 c .get_log_page .lpol = cpu_to_le32 (lower_32_bits (offset ));
28672867 c .get_log_page .lpou = cpu_to_le32 (upper_32_bits (offset ));
2868+ c .get_log_page .csi = csi ;
28682869
28692870 return nvme_submit_sync_cmd (ctrl -> admin_q , & c , log , size );
28702871}
28712872
2872- static int nvme_get_effects_log (struct nvme_ctrl * ctrl )
2873+ static struct nvme_cel * nvme_find_cel (struct nvme_ctrl * ctrl , u8 csi )
28732874{
2875+ struct nvme_cel * cel , * ret = NULL ;
2876+
2877+ spin_lock (& ctrl -> lock );
2878+ list_for_each_entry (cel , & ctrl -> cels , entry ) {
2879+ if (cel -> csi == csi ) {
2880+ ret = cel ;
2881+ break ;
2882+ }
2883+ }
2884+ spin_unlock (& ctrl -> lock );
2885+
2886+ return ret ;
2887+ }
2888+
2889+ static int nvme_get_effects_log (struct nvme_ctrl * ctrl , u8 csi ,
2890+ struct nvme_effects_log * * log )
2891+ {
2892+ struct nvme_cel * cel = nvme_find_cel (ctrl , csi );
28742893 int ret ;
28752894
2876- if (! ctrl -> effects )
2877- ctrl -> effects = kzalloc ( sizeof ( * ctrl -> effects ), GFP_KERNEL ) ;
2895+ if (cel )
2896+ goto out ;
28782897
2879- if (!ctrl -> effects )
2880- return 0 ;
2898+ cel = kzalloc (sizeof (* cel ), GFP_KERNEL );
2899+ if (!cel )
2900+ return - ENOMEM ;
28812901
2882- ret = nvme_get_log (ctrl , NVME_NSID_ALL , NVME_LOG_CMD_EFFECTS , 0 ,
2883- ctrl -> effects , sizeof (* ctrl -> effects ), 0 );
2902+ ret = nvme_get_log (ctrl , NVME_NSID_ALL , NVME_LOG_CMD_EFFECTS , 0 , csi ,
2903+ & cel -> log , sizeof (cel -> log ), 0 );
28842904 if (ret ) {
2885- kfree (ctrl -> effects );
2886- ctrl -> effects = NULL ;
2905+ kfree (cel );
2906+ return ret ;
28872907 }
2888- return ret ;
2908+
2909+ cel -> csi = csi ;
2910+
2911+ spin_lock (& ctrl -> lock );
2912+ list_add_tail (& cel -> entry , & ctrl -> cels );
2913+ spin_unlock (& ctrl -> lock );
2914+ out :
2915+ * log = & cel -> log ;
2916+ return 0 ;
28892917}
28902918
28912919/*
@@ -2918,7 +2946,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
29182946 }
29192947
29202948 if (id -> lpa & NVME_CTRL_LPA_CMD_EFFECTS_LOG ) {
2921- ret = nvme_get_effects_log (ctrl );
2949+ ret = nvme_get_effects_log (ctrl , NVME_CSI_NVM , & ctrl -> effects );
29222950 if (ret < 0 )
29232951 goto out_free ;
29242952 }
@@ -3551,6 +3579,13 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
35513579 goto out_cleanup_srcu ;
35523580 }
35533581
3582+ if (head -> ids .csi ) {
3583+ ret = nvme_get_effects_log (ctrl , head -> ids .csi , & head -> effects );
3584+ if (ret )
3585+ goto out_cleanup_srcu ;
3586+ } else
3587+ head -> effects = ctrl -> effects ;
3588+
35543589 ret = nvme_mpath_alloc_disk (ctrl , head );
35553590 if (ret )
35563591 goto out_cleanup_srcu ;
@@ -3891,8 +3926,8 @@ static void nvme_clear_changed_ns_log(struct nvme_ctrl *ctrl)
38913926 * raced with us in reading the log page, which could cause us to miss
38923927 * updates.
38933928 */
3894- error = nvme_get_log (ctrl , NVME_NSID_ALL , NVME_LOG_CHANGED_NS , 0 , log ,
3895- log_size , 0 );
3929+ error = nvme_get_log (ctrl , NVME_NSID_ALL , NVME_LOG_CHANGED_NS , 0 ,
3930+ NVME_CSI_NVM , log , log_size , 0 );
38963931 if (error )
38973932 dev_warn (ctrl -> device ,
38983933 "reading changed ns log failed: %d\n" , error );
@@ -4036,8 +4071,8 @@ static void nvme_get_fw_slot_info(struct nvme_ctrl *ctrl)
40364071 if (!log )
40374072 return ;
40384073
4039- if (nvme_get_log (ctrl , NVME_NSID_ALL , NVME_LOG_FW_SLOT , 0 , log ,
4040- sizeof (* log ), 0 ))
4074+ if (nvme_get_log (ctrl , NVME_NSID_ALL , NVME_LOG_FW_SLOT , 0 , NVME_CSI_NVM ,
4075+ log , sizeof (* log ), 0 ))
40414076 dev_warn (ctrl -> device , "Get FW SLOT INFO log error\n" );
40424077 kfree (log );
40434078}
@@ -4174,11 +4209,16 @@ static void nvme_free_ctrl(struct device *dev)
41744209 struct nvme_ctrl * ctrl =
41754210 container_of (dev , struct nvme_ctrl , ctrl_device );
41764211 struct nvme_subsystem * subsys = ctrl -> subsys ;
4212+ struct nvme_cel * cel , * next ;
41774213
41784214 if (subsys && ctrl -> instance != subsys -> instance )
41794215 ida_simple_remove (& nvme_instance_ida , ctrl -> instance );
41804216
4181- kfree (ctrl -> effects );
4217+ list_for_each_entry_safe (cel , next , & ctrl -> cels , entry ) {
4218+ list_del (& cel -> entry );
4219+ kfree (cel );
4220+ }
4221+
41824222 nvme_mpath_uninit (ctrl );
41834223 __free_page (ctrl -> discard_page );
41844224
@@ -4209,6 +4249,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
42094249 spin_lock_init (& ctrl -> lock );
42104250 mutex_init (& ctrl -> scan_lock );
42114251 INIT_LIST_HEAD (& ctrl -> namespaces );
4252+ INIT_LIST_HEAD (& ctrl -> cels );
42124253 init_rwsem (& ctrl -> namespaces_rwsem );
42134254 ctrl -> dev = dev ;
42144255 ctrl -> ops = ops ;
0 commit comments