@@ -81,6 +81,7 @@ enum { CTB_SEND = 0, CTB_RECV = 1 };
81
81
82
82
enum { CTB_OWNER_HOST = 0 };
83
83
84
+ static void ct_receive_tasklet_func (struct tasklet_struct * t );
84
85
static void ct_incoming_request_worker_func (struct work_struct * w );
85
86
86
87
/**
@@ -95,6 +96,7 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
95
96
INIT_LIST_HEAD (& ct -> requests .pending );
96
97
INIT_LIST_HEAD (& ct -> requests .incoming );
97
98
INIT_WORK (& ct -> requests .worker , ct_incoming_request_worker_func );
99
+ tasklet_setup (& ct -> receive_tasklet , ct_receive_tasklet_func );
98
100
}
99
101
100
102
static inline const char * guc_ct_buffer_type_to_str (u32 type )
@@ -244,6 +246,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct)
244
246
{
245
247
GEM_BUG_ON (ct -> enabled );
246
248
249
+ tasklet_kill (& ct -> receive_tasklet );
247
250
i915_vma_unpin_and_release (& ct -> vma , I915_VMA_RELEASE_MAP );
248
251
memset (ct , 0 , sizeof (* ct ));
249
252
}
@@ -651,7 +654,7 @@ static int ct_read(struct intel_guc_ct *ct, u32 *data)
651
654
CT_DEBUG (ct , "received %*ph\n" , 4 * len , data );
652
655
653
656
desc -> head = head * 4 ;
654
- return 0 ;
657
+ return available - len ;
655
658
656
659
corrupted :
657
660
CT_ERROR (ct , "Corrupted descriptor addr=%#x head=%u tail=%u size=%u\n" ,
@@ -687,10 +690,10 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg)
687
690
u32 status ;
688
691
u32 datalen ;
689
692
struct ct_request * req ;
693
+ unsigned long flags ;
690
694
bool found = false;
691
695
692
696
GEM_BUG_ON (!ct_header_is_response (header ));
693
- GEM_BUG_ON (!in_irq ());
694
697
695
698
/* Response payload shall at least include fence and status */
696
699
if (unlikely (len < 2 )) {
@@ -710,7 +713,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg)
710
713
711
714
CT_DEBUG (ct , "response fence %u status %#x\n" , fence , status );
712
715
713
- spin_lock (& ct -> requests .lock );
716
+ spin_lock_irqsave (& ct -> requests .lock , flags );
714
717
list_for_each_entry (req , & ct -> requests .pending , link ) {
715
718
if (unlikely (fence != req -> fence )) {
716
719
CT_DEBUG (ct , "request %u awaits response\n" ,
@@ -729,7 +732,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg)
729
732
found = true;
730
733
break ;
731
734
}
732
- spin_unlock (& ct -> requests .lock );
735
+ spin_unlock_irqrestore (& ct -> requests .lock , flags );
733
736
734
737
if (!found )
735
738
CT_ERROR (ct , "Unsolicited response %*ph\n" , msgsize , msg );
@@ -843,31 +846,55 @@ static int ct_handle_request(struct intel_guc_ct *ct, const u32 *msg)
843
846
return 0 ;
844
847
}
845
848
849
+ static int ct_receive (struct intel_guc_ct * ct )
850
+ {
851
+ u32 msg [GUC_CT_MSG_LEN_MASK + 1 ]; /* one extra dw for the header */
852
+ unsigned long flags ;
853
+ int ret ;
854
+
855
+ spin_lock_irqsave (& ct -> ctbs .recv .lock , flags );
856
+ ret = ct_read (ct , msg );
857
+ spin_unlock_irqrestore (& ct -> ctbs .recv .lock , flags );
858
+ if (ret < 0 )
859
+ return ret ;
860
+
861
+ if (ct_header_is_response (msg [0 ]))
862
+ ct_handle_response (ct , msg );
863
+ else
864
+ ct_handle_request (ct , msg );
865
+
866
+ return ret ;
867
+ }
868
+
869
+ static void ct_try_receive_message (struct intel_guc_ct * ct )
870
+ {
871
+ int ret ;
872
+
873
+ if (GEM_WARN_ON (!ct -> enabled ))
874
+ return ;
875
+
876
+ ret = ct_receive (ct );
877
+ if (ret > 0 )
878
+ tasklet_hi_schedule (& ct -> receive_tasklet );
879
+ }
880
+
881
+ static void ct_receive_tasklet_func (struct tasklet_struct * t )
882
+ {
883
+ struct intel_guc_ct * ct = from_tasklet (ct , t , receive_tasklet );
884
+
885
+ ct_try_receive_message (ct );
886
+ }
887
+
846
888
/*
847
889
* When we're communicating with the GuC over CT, GuC uses events
848
890
* to notify us about new messages being posted on the RECV buffer.
849
891
*/
850
892
void intel_guc_ct_event_handler (struct intel_guc_ct * ct )
851
893
{
852
- u32 msg [GUC_CT_MSG_LEN_MASK + 1 ]; /* one extra dw for the header */
853
- unsigned long flags ;
854
- int err = 0 ;
855
-
856
894
if (unlikely (!ct -> enabled )) {
857
895
WARN (1 , "Unexpected GuC event received while CT disabled!\n" );
858
896
return ;
859
897
}
860
898
861
- do {
862
- spin_lock_irqsave (& ct -> ctbs .recv .lock , flags );
863
- err = ct_read (ct , msg );
864
- spin_unlock_irqrestore (& ct -> ctbs .recv .lock , flags );
865
- if (err )
866
- break ;
867
-
868
- if (ct_header_is_response (msg [0 ]))
869
- err = ct_handle_response (ct , msg );
870
- else
871
- err = ct_handle_request (ct , msg );
872
- } while (!err );
899
+ ct_try_receive_message (ct );
873
900
}
0 commit comments