@@ -103,6 +103,33 @@ enum { CTB_SEND = 0, CTB_RECV = 1 };
103103
104104enum { CTB_OWNER_HOST = 0 };
105105
106+ /*
107+ * Some H2G commands involve a synchronous response that the driver needs
108+ * to wait for. In such cases, a timeout is required to prevent the driver
109+ * from waiting forever in the case of an error (either no error response
110+ * is defined in the protocol or something has died and requires a reset).
111+ * The specific command may be defined as having a time bound response but
112+ * the CT is a queue and that time guarantee only starts from the point
113+ * when the command reaches the head of the queue and is processed by GuC.
114+ *
115+ * Ideally there would be a helper to report the progress of a given
116+ * command through the CT. However, that would require a significant
117+ * amount of work in the CT layer. In the meantime, provide a reasonable
118+ * estimation of the worst case latency it should take for the entire
119+ * queue to drain. And therefore, how long a caller should wait before
120+ * giving up on their request. The current estimate is based on empirical
121+ * measurement of a test that fills the buffer with context creation and
122+ * destruction requests as they seem to be the slowest operation.
123+ */
124+ long intel_guc_ct_max_queue_time_jiffies (void )
125+ {
126+ /*
127+ * A 4KB buffer full of context destroy commands takes a little
128+ * over a second to process so bump that to 2s to be super safe.
129+ */
130+ return (CTB_H2G_BUFFER_SIZE * HZ ) / SZ_2K ;
131+ }
132+
106133static void ct_receive_tasklet_func (struct tasklet_struct * t );
107134static void ct_incoming_request_worker_func (struct work_struct * w );
108135
@@ -1115,6 +1142,9 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
11151142 case INTEL_GUC_ACTION_NOTIFY_EXCEPTION :
11161143 ret = intel_guc_crash_process_msg (guc , action );
11171144 break ;
1145+ case INTEL_GUC_ACTION_TLB_INVALIDATION_DONE :
1146+ ret = intel_guc_tlb_invalidation_done (guc , payload , len );
1147+ break ;
11181148 default :
11191149 ret = - EOPNOTSUPP ;
11201150 break ;
@@ -1186,9 +1216,17 @@ static int ct_handle_event(struct intel_guc_ct *ct, struct ct_incoming_msg *requ
11861216 switch (action ) {
11871217 case INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE :
11881218 case INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE :
1219+ case INTEL_GUC_ACTION_TLB_INVALIDATION_DONE :
11891220 g2h_release_space (ct , request -> size );
11901221 }
11911222
1223+ /*
1224+ * TLB invalidation responses must be handled immediately as processing
1225+ * of other G2H notifications may be blocked by an invalidation request.
1226+ */
1227+ if (action == INTEL_GUC_ACTION_TLB_INVALIDATION_DONE )
1228+ return ct_process_request (ct , request );
1229+
11921230 spin_lock_irqsave (& ct -> requests .lock , flags );
11931231 list_add_tail (& request -> link , & ct -> requests .incoming );
11941232 spin_unlock_irqrestore (& ct -> requests .lock , flags );
0 commit comments