@@ -686,6 +686,15 @@ static void qdio_kick_handler(struct qdio_q *q)
686686 q -> qdio_error = 0 ;
687687}
688688
689+ static inline int qdio_tasklet_schedule (struct qdio_q * q )
690+ {
691+ if (likely (q -> irq_ptr -> state == QDIO_IRQ_STATE_ACTIVE )) {
692+ tasklet_schedule (& q -> tasklet );
693+ return 0 ;
694+ }
695+ return - EPERM ;
696+ }
697+
689698static void __qdio_inbound_processing (struct qdio_q * q )
690699{
691700 qperf_inc (q , tasklet_inbound );
@@ -698,10 +707,8 @@ static void __qdio_inbound_processing(struct qdio_q *q)
698707 if (!qdio_inbound_q_done (q )) {
699708 /* means poll time is not yet over */
700709 qperf_inc (q , tasklet_inbound_resched );
701- if (likely (q -> irq_ptr -> state != QDIO_IRQ_STATE_STOPPED )) {
702- tasklet_schedule (& q -> tasklet );
710+ if (!qdio_tasklet_schedule (q ))
703711 return ;
704- }
705712 }
706713
707714 qdio_stop_polling (q );
@@ -711,8 +718,7 @@ static void __qdio_inbound_processing(struct qdio_q *q)
711718 */
712719 if (!qdio_inbound_q_done (q )) {
713720 qperf_inc (q , tasklet_inbound_resched2 );
714- if (likely (q -> irq_ptr -> state != QDIO_IRQ_STATE_STOPPED ))
715- tasklet_schedule (& q -> tasklet );
721+ qdio_tasklet_schedule (q );
716722 }
717723}
718724
@@ -869,16 +875,15 @@ static void __qdio_outbound_processing(struct qdio_q *q)
869875 * is noticed and outbound_handler is called after some time.
870876 */
871877 if (qdio_outbound_q_done (q ))
872- del_timer (& q -> u .out .timer );
878+ del_timer_sync (& q -> u .out .timer );
873879 else
874- if (!timer_pending (& q -> u .out .timer ))
880+ if (!timer_pending (& q -> u .out .timer ) &&
881+ likely (q -> irq_ptr -> state == QDIO_IRQ_STATE_ACTIVE ))
875882 mod_timer (& q -> u .out .timer , jiffies + 10 * HZ );
876883 return ;
877884
878885sched :
879- if (unlikely (q -> irq_ptr -> state == QDIO_IRQ_STATE_STOPPED ))
880- return ;
881- tasklet_schedule (& q -> tasklet );
886+ qdio_tasklet_schedule (q );
882887}
883888
884889/* outbound tasklet */
@@ -892,9 +897,7 @@ void qdio_outbound_timer(unsigned long data)
892897{
893898 struct qdio_q * q = (struct qdio_q * )data ;
894899
895- if (unlikely (q -> irq_ptr -> state == QDIO_IRQ_STATE_STOPPED ))
896- return ;
897- tasklet_schedule (& q -> tasklet );
900+ qdio_tasklet_schedule (q );
898901}
899902
900903static inline void qdio_check_outbound_after_thinint (struct qdio_q * q )
@@ -907,7 +910,7 @@ static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
907910
908911 for_each_output_queue (q -> irq_ptr , out , i )
909912 if (!qdio_outbound_q_done (out ))
910- tasklet_schedule ( & out -> tasklet );
913+ qdio_tasklet_schedule ( out );
911914}
912915
913916static void __tiqdio_inbound_processing (struct qdio_q * q )
@@ -929,10 +932,8 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
929932
930933 if (!qdio_inbound_q_done (q )) {
931934 qperf_inc (q , tasklet_inbound_resched );
932- if (likely (q -> irq_ptr -> state != QDIO_IRQ_STATE_STOPPED )) {
933- tasklet_schedule (& q -> tasklet );
935+ if (!qdio_tasklet_schedule (q ))
934936 return ;
935- }
936937 }
937938
938939 qdio_stop_polling (q );
@@ -942,8 +943,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
942943 */
943944 if (!qdio_inbound_q_done (q )) {
944945 qperf_inc (q , tasklet_inbound_resched2 );
945- if (likely (q -> irq_ptr -> state != QDIO_IRQ_STATE_STOPPED ))
946- tasklet_schedule (& q -> tasklet );
946+ qdio_tasklet_schedule (q );
947947 }
948948}
949949
@@ -977,7 +977,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
977977 int i ;
978978 struct qdio_q * q ;
979979
980- if (unlikely (irq_ptr -> state == QDIO_IRQ_STATE_STOPPED ))
980+ if (unlikely (irq_ptr -> state != QDIO_IRQ_STATE_ACTIVE ))
981981 return ;
982982
983983 for_each_input_queue (irq_ptr , q , i ) {
@@ -1003,7 +1003,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
10031003 continue ;
10041004 if (need_siga_sync (q ) && need_siga_sync_out_after_pci (q ))
10051005 qdio_siga_sync_q (q );
1006- tasklet_schedule ( & q -> tasklet );
1006+ qdio_tasklet_schedule ( q );
10071007 }
10081008}
10091009
@@ -1145,7 +1145,7 @@ static void qdio_shutdown_queues(struct ccw_device *cdev)
11451145 tasklet_kill (& q -> tasklet );
11461146
11471147 for_each_output_queue (irq_ptr , q , i ) {
1148- del_timer (& q -> u .out .timer );
1148+ del_timer_sync (& q -> u .out .timer );
11491149 tasklet_kill (& q -> tasklet );
11501150 }
11511151}
@@ -1585,10 +1585,11 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
15851585
15861586 /* in case of SIGA errors we must process the error immediately */
15871587 if (used >= q -> u .out .scan_threshold || rc )
1588- tasklet_schedule ( & q -> tasklet );
1588+ qdio_tasklet_schedule ( q );
15891589 else
15901590 /* free the SBALs in case of no further traffic */
1591- if (!timer_pending (& q -> u .out .timer ))
1591+ if (!timer_pending (& q -> u .out .timer ) &&
1592+ likely (q -> irq_ptr -> state == QDIO_IRQ_STATE_ACTIVE ))
15921593 mod_timer (& q -> u .out .timer , jiffies + HZ );
15931594 return rc ;
15941595}
0 commit comments