@@ -257,13 +257,12 @@ static void eeh_pe_report_edev(struct eeh_dev *edev, eeh_report_fn fn,
257
257
struct pci_driver * driver ;
258
258
enum pci_ers_result new_result ;
259
259
260
- pci_lock_rescan_remove ();
261
260
pdev = edev -> pdev ;
262
261
if (pdev )
263
262
get_device (& pdev -> dev );
264
- pci_unlock_rescan_remove ();
265
263
if (!pdev ) {
266
264
eeh_edev_info (edev , "no device" );
265
+ * result = PCI_ERS_RESULT_DISCONNECT ;
267
266
return ;
268
267
}
269
268
device_lock (& pdev -> dev );
@@ -304,8 +303,9 @@ static void eeh_pe_report(const char *name, struct eeh_pe *root,
304
303
struct eeh_dev * edev , * tmp ;
305
304
306
305
pr_info ("EEH: Beginning: '%s'\n" , name );
307
- eeh_for_each_pe (root , pe ) eeh_pe_for_each_dev (pe , edev , tmp )
308
- eeh_pe_report_edev (edev , fn , result );
306
+ eeh_for_each_pe (root , pe )
307
+ eeh_pe_for_each_dev (pe , edev , tmp )
308
+ eeh_pe_report_edev (edev , fn , result );
309
309
if (result )
310
310
pr_info ("EEH: Finished:'%s' with aggregate recovery state:'%s'\n" ,
311
311
name , pci_ers_result_name (* result ));
@@ -383,6 +383,8 @@ static void eeh_dev_restore_state(struct eeh_dev *edev, void *userdata)
383
383
if (!edev )
384
384
return ;
385
385
386
+ pci_lock_rescan_remove ();
387
+
386
388
/*
387
389
* The content in the config space isn't saved because
388
390
* the blocked config space on some adapters. We have
@@ -393,14 +395,19 @@ static void eeh_dev_restore_state(struct eeh_dev *edev, void *userdata)
393
395
if (list_is_last (& edev -> entry , & edev -> pe -> edevs ))
394
396
eeh_pe_restore_bars (edev -> pe );
395
397
398
+ pci_unlock_rescan_remove ();
396
399
return ;
397
400
}
398
401
399
402
pdev = eeh_dev_to_pci_dev (edev );
400
- if (!pdev )
403
+ if (!pdev ) {
404
+ pci_unlock_rescan_remove ();
401
405
return ;
406
+ }
402
407
403
408
pci_restore_state (pdev );
409
+
410
+ pci_unlock_rescan_remove ();
404
411
}
405
412
406
413
/**
@@ -647,9 +654,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
647
654
if (any_passed || driver_eeh_aware || (pe -> type & EEH_PE_VF )) {
648
655
eeh_pe_dev_traverse (pe , eeh_rmv_device , rmv_data );
649
656
} else {
650
- pci_lock_rescan_remove ();
651
657
pci_hp_remove_devices (bus );
652
- pci_unlock_rescan_remove ();
653
658
}
654
659
655
660
/*
@@ -665,16 +670,13 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
665
670
if (rc )
666
671
return rc ;
667
672
668
- pci_lock_rescan_remove ();
669
-
670
673
/* Restore PE */
671
674
eeh_ops -> configure_bridge (pe );
672
675
eeh_pe_restore_bars (pe );
673
676
674
677
/* Clear frozen state */
675
678
rc = eeh_clear_pe_frozen_state (pe , false);
676
679
if (rc ) {
677
- pci_unlock_rescan_remove ();
678
680
return rc ;
679
681
}
680
682
@@ -709,7 +711,6 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
709
711
pe -> tstamp = tstamp ;
710
712
pe -> freeze_count = cnt ;
711
713
712
- pci_unlock_rescan_remove ();
713
714
return 0 ;
714
715
}
715
716
@@ -843,10 +844,13 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
843
844
{LIST_HEAD_INIT (rmv_data .removed_vf_list ), 0 };
844
845
int devices = 0 ;
845
846
847
+ pci_lock_rescan_remove ();
848
+
846
849
bus = eeh_pe_bus_get (pe );
847
850
if (!bus ) {
848
851
pr_err ("%s: Cannot find PCI bus for PHB#%x-PE#%x\n" ,
849
852
__func__ , pe -> phb -> global_number , pe -> addr );
853
+ pci_unlock_rescan_remove ();
850
854
return ;
851
855
}
852
856
@@ -1094,10 +1098,15 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
1094
1098
eeh_pe_state_clear (pe , EEH_PE_PRI_BUS , true);
1095
1099
eeh_pe_dev_mode_mark (pe , EEH_DEV_REMOVED );
1096
1100
1097
- pci_lock_rescan_remove ();
1098
- pci_hp_remove_devices (bus );
1099
- pci_unlock_rescan_remove ();
1101
+ bus = eeh_pe_bus_get (pe );
1102
+ if (bus )
1103
+ pci_hp_remove_devices (bus );
1104
+ else
1105
+ pr_err ("%s: PCI bus for PHB#%x-PE#%x disappeared\n" ,
1106
+ __func__ , pe -> phb -> global_number , pe -> addr );
1107
+
1100
1108
/* The passed PE should no longer be used */
1109
+ pci_unlock_rescan_remove ();
1101
1110
return ;
1102
1111
}
1103
1112
@@ -1114,6 +1123,8 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
1114
1123
eeh_clear_slot_attention (edev -> pdev );
1115
1124
1116
1125
eeh_pe_state_clear (pe , EEH_PE_RECOVERING , true);
1126
+
1127
+ pci_unlock_rescan_remove ();
1117
1128
}
1118
1129
1119
1130
/**
@@ -1132,6 +1143,7 @@ void eeh_handle_special_event(void)
1132
1143
unsigned long flags ;
1133
1144
int rc ;
1134
1145
1146
+ pci_lock_rescan_remove ();
1135
1147
1136
1148
do {
1137
1149
rc = eeh_ops -> next_error (& pe );
@@ -1171,10 +1183,12 @@ void eeh_handle_special_event(void)
1171
1183
1172
1184
break ;
1173
1185
case EEH_NEXT_ERR_NONE :
1186
+ pci_unlock_rescan_remove ();
1174
1187
return ;
1175
1188
default :
1176
1189
pr_warn ("%s: Invalid value %d from next_error()\n" ,
1177
1190
__func__ , rc );
1191
+ pci_unlock_rescan_remove ();
1178
1192
return ;
1179
1193
}
1180
1194
@@ -1186,7 +1200,9 @@ void eeh_handle_special_event(void)
1186
1200
if (rc == EEH_NEXT_ERR_FROZEN_PE ||
1187
1201
rc == EEH_NEXT_ERR_FENCED_PHB ) {
1188
1202
eeh_pe_state_mark (pe , EEH_PE_RECOVERING );
1203
+ pci_unlock_rescan_remove ();
1189
1204
eeh_handle_normal_event (pe );
1205
+ pci_lock_rescan_remove ();
1190
1206
} else {
1191
1207
eeh_for_each_pe (pe , tmp_pe )
1192
1208
eeh_pe_for_each_dev (tmp_pe , edev , tmp_edev )
@@ -1199,7 +1215,6 @@ void eeh_handle_special_event(void)
1199
1215
eeh_report_failure , NULL );
1200
1216
eeh_set_channel_state (pe , pci_channel_io_perm_failure );
1201
1217
1202
- pci_lock_rescan_remove ();
1203
1218
list_for_each_entry (hose , & hose_list , list_node ) {
1204
1219
phb_pe = eeh_phb_pe_get (hose );
1205
1220
if (!phb_pe ||
@@ -1218,7 +1233,6 @@ void eeh_handle_special_event(void)
1218
1233
}
1219
1234
pci_hp_remove_devices (bus );
1220
1235
}
1221
- pci_unlock_rescan_remove ();
1222
1236
}
1223
1237
1224
1238
/*
@@ -1228,4 +1242,6 @@ void eeh_handle_special_event(void)
1228
1242
if (rc == EEH_NEXT_ERR_DEAD_IOC )
1229
1243
break ;
1230
1244
} while (rc != EEH_NEXT_ERR_NONE );
1245
+
1246
+ pci_unlock_rescan_remove ();
1231
1247
}
0 commit comments