@@ -127,6 +127,16 @@ static struct workqueue_struct *qla_tgt_wq;
127
127
static DEFINE_MUTEX (qla_tgt_mutex );
128
128
static LIST_HEAD (qla_tgt_glist );
129
129
130
+ /* This API intentionally takes dest as a parameter, rather than returning
131
+ * int value to avoid caller forgetting to issue wmb() after the store */
132
+ void qlt_do_generation_tick (struct scsi_qla_host * vha , int * dest )
133
+ {
134
+ scsi_qla_host_t * base_vha = pci_get_drvdata (vha -> hw -> pdev );
135
+ * dest = atomic_inc_return (& base_vha -> generation_tick );
136
+ /* memory barrier */
137
+ wmb ();
138
+ }
139
+
130
140
/* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list) */
131
141
static struct qla_tgt_sess * qlt_find_sess_by_port_name (
132
142
struct qla_tgt * tgt ,
@@ -576,10 +586,12 @@ static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess,
576
586
sess -> expires = jiffies + dev_loss_tmo * HZ ;
577
587
578
588
ql_dbg (ql_dbg_tgt , sess -> vha , 0xe048 ,
579
- "qla_target(%d): session for port %8phC (loop ID %d) scheduled for "
580
- "deletion in %u secs (expires: %lu) immed: %d, logout: %d\n" ,
581
- sess -> vha -> vp_idx , sess -> port_name , sess -> loop_id , dev_loss_tmo ,
582
- sess -> expires , immediate , sess -> logout_on_delete );
589
+ "qla_target(%d): session for port %8phC (loop ID %d s_id %02x:%02x:%02x)"
590
+ " scheduled for deletion in %u secs (expires: %lu) immed: %d, logout: %d, gen: %#x\n" ,
591
+ sess -> vha -> vp_idx , sess -> port_name , sess -> loop_id ,
592
+ sess -> s_id .b .domain , sess -> s_id .b .area , sess -> s_id .b .al_pa ,
593
+ dev_loss_tmo , sess -> expires , immediate , sess -> logout_on_delete ,
594
+ sess -> generation );
583
595
584
596
if (immediate )
585
597
mod_delayed_work (system_wq , & tgt -> sess_del_work , 0 );
@@ -734,6 +746,9 @@ static struct qla_tgt_sess *qlt_create_sess(
734
746
735
747
if (sess -> local && !local )
736
748
sess -> local = 0 ;
749
+
750
+ qlt_do_generation_tick (vha , & sess -> generation );
751
+
737
752
spin_unlock_irqrestore (& ha -> hardware_lock , flags );
738
753
739
754
return sess ;
@@ -795,6 +810,7 @@ static struct qla_tgt_sess *qlt_create_sess(
795
810
spin_lock_irqsave (& ha -> hardware_lock , flags );
796
811
list_add_tail (& sess -> sess_list_entry , & vha -> vha_tgt .qla_tgt -> sess_list );
797
812
vha -> vha_tgt .qla_tgt -> sess_count ++ ;
813
+ qlt_do_generation_tick (vha , & sess -> generation );
798
814
spin_unlock_irqrestore (& ha -> hardware_lock , flags );
799
815
800
816
ql_dbg (ql_dbg_tgt_mgt , vha , 0xf04b ,
@@ -808,7 +824,7 @@ static struct qla_tgt_sess *qlt_create_sess(
808
824
}
809
825
810
826
/*
811
- * Called from drivers/scsi/qla2xxx/qla_init.c: qla2x00_reg_remote_port()
827
+ * Called from qla2x00_reg_remote_port()
812
828
*/
813
829
void qlt_fc_port_added (struct scsi_qla_host * vha , fc_port_t * fcport )
814
830
{
@@ -874,7 +890,12 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
874
890
spin_unlock_irqrestore (& ha -> hardware_lock , flags );
875
891
}
876
892
877
- void qlt_fc_port_deleted (struct scsi_qla_host * vha , fc_port_t * fcport )
893
+ /*
894
+ * max_gen - specifies maximum session generation
895
+ * at which this deletion requestion is still valid
896
+ */
897
+ void
898
+ qlt_fc_port_deleted (struct scsi_qla_host * vha , fc_port_t * fcport , int max_gen )
878
899
{
879
900
struct qla_tgt * tgt = vha -> vha_tgt .qla_tgt ;
880
901
struct qla_tgt_sess * sess ;
@@ -893,6 +914,15 @@ void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
893
914
return ;
894
915
}
895
916
917
+ if (max_gen - sess -> generation < 0 ) {
918
+ ql_dbg (ql_dbg_tgt_mgt , vha , 0xf092 ,
919
+ "Ignoring stale deletion request for se_sess %p / sess %p"
920
+ " for port %8phC, req_gen %d, sess_gen %d\n" ,
921
+ sess -> se_sess , sess , sess -> port_name , max_gen ,
922
+ sess -> generation );
923
+ return ;
924
+ }
925
+
896
926
ql_dbg (ql_dbg_tgt_mgt , vha , 0xf008 , "qla_tgt_fc_port_deleted %p" , sess );
897
927
898
928
sess -> local = 1 ;
@@ -3970,7 +4000,7 @@ void qlt_logo_completion_handler(fc_port_t *fcport, int rc)
3970
4000
{
3971
4001
if (fcport -> tgt_session ) {
3972
4002
if (rc != MBS_COMMAND_COMPLETE ) {
3973
- ql_dbg (ql_dbg_tgt_mgt , fcport -> vha , 0xf088 ,
4003
+ ql_dbg (ql_dbg_tgt_mgt , fcport -> vha , 0xf093 ,
3974
4004
"%s: se_sess %p / sess %p from"
3975
4005
" port %8phC loop_id %#04x s_id %02x:%02x:%02x"
3976
4006
" LOGO failed: %#x\n" ,
@@ -4099,6 +4129,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
4099
4129
struct imm_ntfy_from_isp * iocb )
4100
4130
{
4101
4131
struct qla_tgt * tgt = vha -> vha_tgt .qla_tgt ;
4132
+ struct qla_hw_data * ha = vha -> hw ;
4102
4133
struct qla_tgt_sess * sess = NULL ;
4103
4134
uint64_t wwn ;
4104
4135
port_id_t port_id ;
@@ -4144,7 +4175,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
4144
4175
* without acking, new one will get acked when session
4145
4176
* deletion completes.
4146
4177
*/
4147
- ql_log (ql_log_warn , sess -> vha , 0xf089 ,
4178
+ ql_log (ql_log_warn , sess -> vha , 0xf094 ,
4148
4179
"sess %p received double plogi.\n" , sess );
4149
4180
4150
4181
qlt_swap_imm_ntfy_iocb (iocb , & sess -> tm_iocb );
@@ -4201,7 +4232,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
4201
4232
* PLOGI could finish. Will force him to re-try,
4202
4233
* while last one finishes.
4203
4234
*/
4204
- ql_log (ql_log_warn , sess -> vha , 0xf090 ,
4235
+ ql_log (ql_log_warn , sess -> vha , 0xf095 ,
4205
4236
"sess %p PRLI received, before plogi ack.\n" ,
4206
4237
sess );
4207
4238
qlt_send_term_imm_notif (vha , iocb , 1 );
@@ -4213,7 +4244,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
4213
4244
* This shouldn't happen under normal circumstances,
4214
4245
* since we have deleted the old session during PLOGI
4215
4246
*/
4216
- ql_dbg (ql_dbg_tgt_mgt , vha , 0xf091 ,
4247
+ ql_dbg (ql_dbg_tgt_mgt , vha , 0xf096 ,
4217
4248
"PRLI (loop_id %#04x) for existing sess %p (loop_id %#04x)\n" ,
4218
4249
sess -> loop_id , sess , iocb -> u .isp24 .nport_handle );
4219
4250
@@ -4224,7 +4255,14 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
4224
4255
if (wd3_lo & BIT_7 )
4225
4256
sess -> conf_compl_supported = 1 ;
4226
4257
4227
- res = 1 ;
4258
+ }
4259
+ res = 1 ; /* send notify ack */
4260
+
4261
+ /* Make session global (not used in fabric mode) */
4262
+ if (ha -> current_topology != ISP_CFG_F ) {
4263
+ set_bit (LOOP_RESYNC_NEEDED , & vha -> dpc_flags );
4264
+ set_bit (LOCAL_LOOP_UPDATE , & vha -> dpc_flags );
4265
+ qla2xxx_wake_dpc (vha );
4228
4266
} else {
4229
4267
/* todo: else - create sess here. */
4230
4268
res = 1 ; /* send notify ack */
0 commit comments