[Intel-gfx] [PATCH v5 09/12] drm/i915/guc: Prepare to process incoming requests from CT

Michel Thierry michel.thierry at intel.com
Tue Mar 27 20:07:28 UTC 2018


On 3/26/2018 12:48 PM, Wajdeczko, Michal wrote:
> Requests are read from CT in the irq handler, but actual processing
> will be done in the work thread. Processing of specific actions will
> be added in the upcoming patches.
> 
> v2: don't use GEM_BUG_ON (Chris)
>      don't kmalloc too large buffer (Michal)
> v3: rebased
> v4: don't name it 'dispatch' (Michel) and fix checkpatch
>      add some documentation (Michal)
> 
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
> Cc: Oscar Mateo <oscar.mateo at intel.com>
> Cc: Michel Thierry <michel.thierry at intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> ---
>   drivers/gpu/drm/i915/intel_guc_ct.c | 95 ++++++++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/i915/intel_guc_ct.h |  6 +++
>   2 files changed, 100 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc_ct.c b/drivers/gpu/drm/i915/intel_guc_ct.c
> index 41b071c..aa810ad 100644
> --- a/drivers/gpu/drm/i915/intel_guc_ct.c
> +++ b/drivers/gpu/drm/i915/intel_guc_ct.c
> @@ -32,10 +32,17 @@ struct ct_request {
>          u32 *response_buf;
>   };
> 
> +struct ct_incoming_request {
> +       struct list_head link;
> +       u32 msg[];
> +};
> +
>   enum { CTB_SEND = 0, CTB_RECV = 1 };
> 
>   enum { CTB_OWNER_HOST = 0 };
> 
> +static void ct_incoming_request_worker_func(struct work_struct *w);
> +
>   /**
>    * intel_guc_ct_init_early - Initialize CT state without requiring device access
>    * @ct: pointer to CT struct
> @@ -47,6 +54,8 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
> 
>          spin_lock_init(&ct->lock);
>          INIT_LIST_HEAD(&ct->pending_requests);
> +       INIT_LIST_HEAD(&ct->incoming_requests);
> +       INIT_WORK(&ct->worker, ct_incoming_request_worker_func);
>   }
> 
>   static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct)
> @@ -682,13 +691,97 @@ static int ct_handle_response(struct intel_guc_ct *ct, const u32 *msg)
>          return 0;
>   }
> 
> +static void ct_process_request(struct intel_guc_ct *ct,
> +                              u32 action, u32 len, const u32 *payload)
> +{
> +       switch (action) {
> +       default:
> +               DRM_ERROR("CT: unexpected request %x %*phn\n",
> +                         action, 4 * len, payload);
> +               break;
> +       }
> +}
> +
> +static bool ct_process_incoming_requests(struct intel_guc_ct *ct)
> +{
> +       unsigned long flags;
> +       struct ct_incoming_request *request;
> +       u32 header;
> +       u32 *payload;
> +       bool done;
> +
> +       spin_lock_irqsave(&ct->lock, flags);
> +       request = list_first_entry_or_null(&ct->incoming_requests,
> +                                          struct ct_incoming_request, link);
> +       if (request)
> +               list_del(&request->link);
> +       done = !!list_empty(&ct->incoming_requests);
> +       spin_unlock_irqrestore(&ct->lock, flags);
> +
> +       if (!request)
> +               return true;
> +
> +       header = request->msg[0];
> +       payload = &request->msg[1];
> +       ct_process_request(ct,
> +                          ct_header_get_action(header),
> +                          ct_header_get_len(header),
> +                          payload);
> +
> +       kfree(request);
> +       return done;
> +}
> +
> +static void ct_incoming_request_worker_func(struct work_struct *w)
> +{
> +       struct intel_guc_ct *ct = container_of(w, struct intel_guc_ct, worker);
> +       bool done;
> +
> +       done = ct_process_incoming_requests(ct);
> +       if (!done)
> +               queue_work(system_unbound_wq, &ct->worker);
> +}
> +
> +/**
> + * DOC: CTB GuC to Host request
> + *
> + * Format of the CTB GuC to Host request message is as follows::
> + *
> + *      +------------+---------+---------+---------+---------+---------+
> + *      |   msg[0]   |   [1]   |   [2]   |   [3]   |   ...   |  [n-1]  |
> + *      +------------+---------+---------+---------+---------+---------+
> + *      |   MESSAGE  |       MESSAGE PAYLOAD                           |
> + *      +   HEADER   +---------+---------+---------+---------+---------+
> + *      |            |    0    |    1    |    2    |   ...   |    n    |
> + *      +============+=========+=========+=========+=========+=========+
> + *      |     len    |            request specific data                |
> + *      +------+-----+---------+---------+---------+---------+---------+
> + *
> + *                   ^-----------------------len-----------------------^
> + */
> +
>   static int ct_handle_request(struct intel_guc_ct *ct, const u32 *msg)
>   {
>          u32 header = msg[0];
> +       u32 len = ct_header_get_len(header);
> +       u32 msglen = len + 1; /* total message length including header */
> +       struct ct_incoming_request *request;
> +       unsigned long flags;
> 
>          GEM_BUG_ON(ct_header_is_response(header));
> 
> -       /* XXX */
> +       request = kmalloc(sizeof(*request) + 4 * msglen, GFP_ATOMIC);
> +       if (unlikely(!request)) {
> +               DRM_ERROR("CT: dropping request %*phn\n", 4 * msglen, msg);
> +               return 0; /* XXX: -ENOMEM ? */
> +       }
> +       memcpy(request->msg, msg, 4 * msglen);
> +
> +       spin_lock_irqsave(&ct->lock, flags);
> +       list_add_tail(&request->link, &ct->incoming_requests);
> +       spin_unlock_irqrestore(&ct->lock, flags);
> +
> +       queue_work(system_unbound_wq, &ct->worker);
>          return 0;
>   }
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc_ct.h b/drivers/gpu/drm/i915/intel_guc_ct.h
> index fac6e53..d774895a 100644
> --- a/drivers/gpu/drm/i915/intel_guc_ct.h
> +++ b/drivers/gpu/drm/i915/intel_guc_ct.h
> @@ -81,6 +81,12 @@ struct intel_guc_ct {
> 
>          /** @pending_requests: list of requests waiting for response */
>          struct list_head pending_requests;
> +
> +       /** @incoming_requests: list of incoming requests */
> +       struct list_head incoming_requests;
> +
> +       /** @worker: worker for handling incoming requests */
> +       struct work_struct worker;
>   };
> 
>   void intel_guc_ct_init_early(struct intel_guc_ct *ct);
> --
> 1.9.1
> 

Reviewed-by: Michel Thierry <michel.thierry at intel.com>


More information about the Intel-gfx mailing list