[Intel-gfx] [PATCH v3 2/3] drm/i915/guc: Introduce buffer based cmd transport
Michal Wajdeczko
michal.wajdeczko at intel.com
Thu May 25 11:32:05 UTC 2017
On Wed, May 24, 2017 at 11:35:15AM -0700, Daniele Ceraolo Spurio wrote:
> <snip>
>
> > +
> > +static int ctch_init(struct intel_guc *guc,
> > + struct intel_guc_ct_channel *ctch)
> > +{
> > + struct i915_vma *vma;
> > + void *blob;
> > + int err;
> > + int i;
> > +
> > + GEM_BUG_ON(ctch->vma);
> > +
> > + /* We allocate 1 page to hold both descriptors and both buffers.
> > + * ___________.....................
> > + * |desc (SEND)| :
> > + * |___________| PAGE/4
> > + * :___________....................:
> > + * |desc (RECV)| :
> > + * |___________| PAGE/4
> > + * :_______________________________:
> > + * |cmds (SEND) |
> > + * | PAGE/4
> > + * |_______________________________|
> > + * |cmds (RECV) |
> > + * | PAGE/4
> > + * |_______________________________|
> > + *
> > + * Each message can use a maximum of 32 dwords and we don't expect to
> > + * have more than 1 in flight at any time, so we have enough space.
> > + * Some logic further ahead will rely on the fact that there is only 1
> > + * page and that it is always mapped, so if the size is changed the
> > + * other code will need updating as well.
> > + */
> > +
> > + /* allocate vma */
> > + vma = intel_guc_allocate_vma(guc, PAGE_SIZE);
> > + if (IS_ERR(vma)) {
> > + err = PTR_ERR(vma);
> > + goto err_out;
> > + }
> > + ctch->vma = vma;
> > +
> > + /* map first page */
> > + blob = i915_gem_object_pin_map(vma->obj, I915_MAP_WB);
> > + if (IS_ERR(blob)) {
> > + err = PTR_ERR(blob);
> > + goto err_vma;
> > + }
> > + DRM_DEBUG_DRIVER("CT: vma base=%#x\n", guc_ggtt_offset(ctch->vma));
> > +
> > + /* store pointers to desc and cmds */
> > + for (i = 0; i < ARRAY_SIZE(ctch->ctbs); i++) {
> > + GEM_BUG_ON((i != CTB_SEND) && (i != CTB_RECV));
> > + ctch->ctbs[i].desc = blob + PAGE_SIZE/4 * i;
> > + ctch->ctbs[i].cmds = blob + PAGE_SIZE/4 * i + PAGE_SIZE/2;
> > + }
> > +
> > + ctch->owner = CTB_OWNER_HOST;
>
> mmmh, this function gets a generic struct intel_guc_ct_channel as input but
> here it assumes that it is the host one. If we want it to be generic then we
> need to pass the owner from outside, otherwise if we assume that this is the
> host channel then we can just do:
>
> ctch = &guc->ct.channel;
>
> without passing it as a parameter. My preference goes to option 1.
>
Yeah, this was just too easy shortcut. Now as we agree that owners ID are static,
I've moved this initialization to the reincarnated guc_ct_init_early(), where
we'll be able to pre-assign owners to all future channels.
>
> <snip>
>
> > diff --git a/drivers/gpu/drm/i915/intel_guc_ct.h b/drivers/gpu/drm/i915/intel_guc_ct.h
> > new file mode 100644
> > index 0000000..8df759d
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/intel_guc_ct.h
> > @@ -0,0 +1,80 @@
> > +/*
> > + * Copyright © 2016-2017 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + */
> > +
> > +#ifndef _INTEL_GUC_CT_H_
> > +#define _INTEL_GUC_CT_H_
> > +
> > +struct intel_guc;
> > +struct i915_vma;
> > +
> > +#include "intel_guc_fwif.h"
> > +
> > +/**
> > + * DOC: Command Transport (CT).
> > + *
> > + * Buffer based command transport is a replacement for MMIO based mechanism.
> > + * It can be used to perform both host-2-guc and guc-to-host communication.
> > + */
> > +
> > +/** Represents single command transport buffer.
> > + *
> > + * A single command transport buffer consists of two parts, the header
> > + * record (command transport buffer descriptor) and the actual buffer which
> > + * holds the commands.
> > + *
> > + * @desc: pointer to the buffer descriptor
> > + * @cmds: pointer to the commands buffer
> > + */
> > +struct intel_guc_ct_buffer {
> > + struct guc_ct_buffer_desc *desc;
> > + u32 *cmds;
> > +};
> > +
> > +/** Represents pair of command transport buffers.
> > + *
> > + * Buffers go in pairs to allow bi-directional communication.
> > + * To simplify the code we place both of them in the same vma.
> > + * Buffers from the same pair must share unique owner id.
> > + *
> > + * @vma: pointer to the vma with pair of CT buffers
> > + * @ctbs: buffers for sending(0) and receiving(1) commands
> > + * @owner: unique identifier
> > + * @next_fence: fence to be used with next send command
> > + */
> > +struct intel_guc_ct_channel {
> > + struct i915_vma *vma;
> > + struct intel_guc_ct_buffer ctbs[2];
> > + u32 owner;
> > + u32 next_fence;
> > +};
> > +
> > +/* */
> > +struct intel_guc_ct {
> > + struct intel_guc_ct_channel channel;
> > +};
>
> Do we still need this structure now that there is no ida? Can't we just use
> intel_guc_ct_channel directly?
Single ct_channel is our (low level) representation of the single CT channel.
As we expect more possible channels, we must be prepared where we locate them.
This higher level guc_ct struct will be a perfect place.
>
> > +
> > +/* XXX: move to intel_uc.h ? don't fit there either */
> > +int intel_guc_enable_ct(struct intel_guc *guc);
> > +void intel_guc_disable_ct(struct intel_guc *guc);
> > +
> > +#endif /* _INTEL_GUC_CT_H_ */
> > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
> > index 6156845..c252e90 100644
> > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> > @@ -331,6 +331,46 @@ struct guc_stage_desc {
> > u64 desc_private;
> > } __packed;
> >
> > +/*
> > + * Describes single command transport buffer.
> > + * Used by both guc-master and clients.
> > + */
> > +struct guc_ct_buffer_desc {
> > + u32 addr; /* gfx address */
> > + u64 host_private; /* owner private data */
> > + u32 size; /* size in bytes */
> > + u32 head; /* offset updated by GuC*/
> > + u32 tail; /* offset updated by owner */
> > + u32 is_in_error; /* error indicator */
> > + u32 fence; /* fence updated by GuC */
> > + u32 status; /* status updated by GuC */
> > + u32 owner; /* id assigned by owner */
>
> maybe something like
>
> /* id of the channel owner */
>
> might be clearer as the owner does not decide its id, it can only decide the
> sub_ids
>
> > + u32 reserved[6];
>
> I know from our IM conversation that you prefer to not define the
> subtracking_id field because we do not use it. However, until now we're
> always kept our definitions in sync with the GuC FW so I'd prefer to do the
> same here. We can use a comment to make the field use clear even if we don't
> use it at the moment.
Ok, I'll add this field.
Thanks,
Michal
More information about the Intel-gfx
mailing list