[PATCH v6 4/8] drm/i915/pxp: Add GSC-CS backend to send GSC fw messages
Teres Alexis, Alan Previn
alan.previn.teres.alexis at intel.com
Fri Mar 24 02:22:00 UTC 2023
Hi Daniele - thanks for reviewing this - i will fix all of code in accordance to the review
comments you provided with some exceptions / alternatives:
On Fri, 2023-03-03 at 17:07 -0800, Ceraolo Spurio, Daniele wrote:
>
> On 2/27/2023 6:21 PM, Alan Previn wrote:
> > Add GSC engine based method for sending PXP firmware packets
> > to the GSC firmware for MTL (and future) products.
> >
> > Use the newly added helpers to populate the GSC-CS memory
> > header and send the message packet to the FW by dispatching
> > the GSC_HECI_CMD_PKT instruction on the GSC engine.
> > +gsccs_send_message(struct intel_pxp *pxp,
> > + void *msg_in, size_t msg_in_size,
> > + void *msg_out, size_t msg_out_size_max,
> > + size_t *msg_out_len,
> > + u64 *gsc_msg_handle_retry)
> > +{
> > + struct intel_gt *gt = pxp->ctrl_gt;
> > + struct drm_i915_private *i915 = gt->i915;
> > + struct gsccs_session_resources *exec = &pxp->gsccs_res;
>
> in the alloc/free functions you called this object *strm_res; IMO better
> to use a consistent naming so it is clear they're the same object
>
alan: agred - actually i think i will go with "exec_res" across the board instead.
alan:snip
> > + max_msg_size = PXP43_MAX_HECI_IN_SIZE - sizeof(*header);
>
> Using the same max_msg_size for both in and out only works if
> PXP43_MAX_HECI_IN_SIZE == PXP43_MAX_HECI_OUT_SIZE. This is true now, but
> I'd add a:
> BUILD_BUG_ON(PXP43_MAX_HECI_IN_SIZE != PXP43_MAX_HECI_OUT_SIZE);
> just to be safe. Potentially also a:
> GEM_BUG_ON(exec->pkt_vma->size < (PXP43_MAX_HECI_IN_SIZE +
> PXP43_MAX_HECI_OUT_SIZE));
> After checking that exec->pkt_vma exists.
>
alan: actually an even simpler alternative would be to just use #define
PXP43_MAX_HECI_INOUT_SIZE - a single definition that will make both
the code and logic easier - it is after reflecting the HW spec too where
the total sizes would be 2xPXP43_MAX_HECI_INOUT_SIZE
alan:snip
>
>
> nit: can't you just use if (!msg_in && !msg_out) instead of a local var?
> not a blocker.
alan:sure
alan:snip
> > + /* Response validity marker, status and busyness */
> > + if (header->validity_marker != GSC_HECI_VALIDITY_MARKER) {
>
> AFAICS you're not clearing the reply header when you re-send the same
> packets after the pending bit, so this marker might be stale data. Same
> for the other fields below.
Good catch - I can clear it before i do the submission - and i assume
you agree that clearing the validity marker alone (in the reply offset)
is sufficient here to strenghten this check.
alan:snip
> >
> > + if (header->flags & GSC_HECI_FLAG_MSG_PENDING) {
> > + drm_dbg(&i915->drm, "gsc PXP reply is busy\n");
> > + /*
> > + * When the GSC firmware replies with pending bit, it means that the requested
> > + * operation has begun but the completion is pending and the caller needs
> > + * to re-request with the gsc_message_handle that was returned by the firmware.
> > + * until the pending bit is turned off.
> > + */
> > + *gsc_msg_handle_retry = header->gsc_message_handle;
>
> Non blocking question: would it be worth it to copy the value to the
> header_in directly, instead of returning the value to the caller and
> copying it on resubmit? Just a thought, I see pro and cons with both
> approaches.
>
alan: Hmm - good idea - okay - let me think about this one... although i
prefer the control be on the caller's side.
alan:snip
> > + } else if (reply_size != msg_out_size_max) {
> > + drm_dbg(&i915->drm, "caller unexpected PXP reply size %u (%ld)\n",
> > + reply_size, msg_out_size_max);
> Are we expecting all caller to always pass the exact size? Not a
> complain, but if that's the case then maybe rename msg_out_size_max to
> msg_out_expected_size, so it's clearer. size_max sounds like any size
> smaller than it is allowed. My personal preference would be to leave
> this as a size_max and have the caller decide if the actual returned
> size matches the expectations (via msg_out_len)
>
No, i am allowing the user to provide buffers bigger than what the reply
In which case you are right- i can let the caller do the size checking.
and remove that dbg msg.
alan:snip
> > + /* all PXP sessions commands are treated as non-priveleged */
> typo priveleged
will fix.
> nit: maybe move gsccs_create_buffer after the cleanup/destruction
> functions? so we can group all the creation functions close together.
>
i was also think of moving functions around to group them but i want to
keep the init/fini right at the bottomg.
> > +static void
> > +gsccs_cleanup_fw_host_session_handle(struct intel_pxp *pxp)
> > +{
> > + struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
> > + int ret;
> > +
> > + ret = gsccs_send_message_retry_complete(pxp, NULL, 0, NULL, 0, NULL);
> > + if (ret)
> > + drm_dbg(&i915->drm, "Failed to send gsccs msg host-session-cleanup: ret=[%d]\n",
> > + ret);
> > +}
> > +
> > static void
> > gsccs_destroy_execution_resource(struct intel_pxp *pxp)
> > {
> > struct gsccs_session_resources *strm_res = &pxp->gsccs_res;
> >
> > + if (strm_res->host_session_handle)
> > + gsccs_cleanup_fw_host_session_handle(pxp);
> > if (strm_res->ce)
> > intel_context_put(strm_res->ce);
> > + if (strm_res->bb_vma)
> > + i915_vma_unpin_and_release(&strm_res->bb_vma, I915_VMA_RELEASE_MAP);
> > + if (strm_res->pkt_vma)
> > + i915_vma_unpin_and_release(&strm_res->pkt_vma, I915_VMA_RELEASE_MAP);
> >
> > memset(strm_res, 0, sizeof(*strm_res));
> > }
> > @@ -30,6 +237,7 @@ gsccs_allocate_execution_resource(struct intel_pxp *pxp)
> > struct gsccs_session_resources *strm_res = &pxp->gsccs_res;
> > struct intel_engine_cs *engine = gt->engine[GSC0];
> > struct intel_context *ce;
> > + int err = 0;
> >
> > /*
> > * First, ensure the GSC engine is present.
> > @@ -38,16 +246,43 @@ gsccs_allocate_execution_resource(struct intel_pxp *pxp)
> > if (!engine)
> > return -ENODEV;
> >
> > + /*
> > + * Now, allocate, pin and map two objects, one for the heci message packet
> > + * and another for the batch buffer we submit into GSC engine (that includes the packet).
> > + * NOTE: GSC-CS backend is currently only supported on MTL, so we allocate shmem.
> > + */
> > + err = gsccs_create_buffer(pxp->ctrl_gt, "Heci Packet",
> > + PXP43_MAX_HECI_IN_SIZE + PXP43_MAX_HECI_OUT_SIZE,
> > + &strm_res->pkt_vma, &strm_res->pkt_vaddr);
> > + if (err)
> > + return err;
> > +
> > + err = gsccs_create_buffer(pxp->ctrl_gt, "Batch Buffer", PAGE_SIZE,
> > + &strm_res->bb_vma, &strm_res->bb_vaddr);
> > + if (err)
> > + goto free_pkt;
> > +
> > /* Finally, create an intel_context to be used during the submission */
> > ce = intel_context_create(engine);
> > if (IS_ERR(ce)) {
> > drm_err(>->i915->drm, "Failed creating gsccs backend ctx\n");
> > - return PTR_ERR(ce);
> > + err = PTR_ERR(ce);
> > + goto free_batch;
> > }
> > -
> > strm_res->ce = ce;
> >
> > + /* initialize host-session-handle (for all i915-to-gsc-firmware PXP cmds) */
> > + get_random_bytes(&strm_res->host_session_handle, sizeof(strm_res->host_session_handle));
>
> This does not guarantee that each host session handle is unique
> (although getting the same u64 twice is going to be extremely extremely
> unlikely). Not sure if it is a problem.
>
yes, you are correct.. i am hoping this is sufficioent.
> > +
> > return 0;
> > +
> > +free_pkt:
> > + i915_vma_unpin_and_release(&strm_res->pkt_vma, I915_VMA_RELEASE_MAP);
> > +free_batch:
> > + i915_vma_unpin_and_release(&strm_res->bb_vma, I915_VMA_RELEASE_MAP);
>
> those gotos are the wrong way around, the pkt is allocated first and
> therefore it should be freed second
alan: yeah - my mistake - will fix it - thanks.
More information about the dri-devel
mailing list