[Intel-gfx] [PATCH 31/32] drm/i915/execlists: Virtual engine bonding
Chris Wilson
chris at chris-wilson.co.uk
Thu Apr 18 06:57:37 UTC 2019
Quoting Tvrtko Ursulin (2019-04-18 07:47:51)
>
> On 17/04/2019 08:56, Chris Wilson wrote:
> > +static void
> > +virtual_bond_execute(struct i915_request *rq, struct dma_fence *signal)
> > +{
> > + struct virtual_engine *ve = to_virtual_engine(rq->engine);
> > + struct ve_bond *bond;
> > +
> > + bond = virtual_find_bond(ve, to_request(signal)->engine);
> > + if (bond) {
> > + intel_engine_mask_t old, new, cmp;
> > +
> > + cmp = READ_ONCE(rq->execution_mask);
> > + do {
> > + old = cmp;
> > + new = cmp & bond->sibling_mask;
> > + } while ((cmp = cmpxchg(&rq->execution_mask, old, new)) != old);
>
> Loop implies someone else might be modifying the rq->execution_mask in
> parallel?
There's nothing that prevents there being multiple bonds being
executed simultaneously (other than practicality). There's also nothing
that says this should be the only way to modify rq->execution_mask in
the future.
> > +static int
> > +set_engines__bond(struct i915_user_extension __user *base, void *data)
> > +{
> > + struct i915_context_engines_bond __user *ext =
> > + container_of_user(base, typeof(*ext), base);
> > + const struct set_engines *set = data;
> > + struct intel_engine_cs *virtual;
> > + struct intel_engine_cs *master;
> > + u16 class, instance;
> > + u16 idx, num_bonds;
> > + int err, n;
> > +
> > + if (get_user(idx, &ext->virtual_index))
> > + return -EFAULT;
> > +
> > + if (idx >= set->engines->num_engines) {
> > + DRM_DEBUG("Invalid index for virtual engine: %d >= %d\n",
> > + idx, set->engines->num_engines);
> > + return -EINVAL;
> > + }
> > +
> > + idx = array_index_nospec(idx, set->engines->num_engines);
> > + if (!set->engines->engines[idx]) {
> > + DRM_DEBUG("Invalid engine at %d\n", idx);
> > + return -EINVAL;
> > + }
> > +
> > + /*
> > + * A non-virtual engine has 0 siblings to choose between; and submit
> > + * fence will always be directed to the one engine.
> > + */
> > + virtual = set->engines->engines[idx]->engine;
> > + if (!intel_engine_is_virtual(virtual))
> > + return 0;
>
> Hmm wouldn't we strictly speaking need to distinguish between uAPI
> errors and auto-magic-single-veng-replacement? Latter is OK to return
> success, but former should be reported as -EINVAL I think.
Is it a uAPI error if it works? :)
> > +
> > + err = check_user_mbz(&ext->flags);
> > + if (err)
> > + return err;
> > +
> > + for (n = 0; n < ARRAY_SIZE(ext->mbz64); n++) {
> > + err = check_user_mbz(&ext->mbz64[n]);
> > + if (err)
> > + return err;
> > + }
> > +
> > + if (get_user(class, &ext->master_class))
> > + return -EFAULT;
> > +
> > + if (get_user(instance, &ext->master_instance))
> > + return -EFAULT;
> > +
> > + master = intel_engine_lookup_user(set->ctx->i915, class, instance);
> > + if (!master) {
> > + DRM_DEBUG("Unrecognised master engine: { class:%d, instance:%d }\n",
> > + class, instance);
> > + return -EINVAL;
> > + }
> > +
> > + if (get_user(num_bonds, &ext->num_bonds))
> > + return -EFAULT;
>
> Should num_bonds > virtual->num_siblings be an error?
They could specify the same bond multiple times for whatever reason (and
probably should allow skipping NONE?), if the target doesn't exist that's
definitely an error.
> > +/*
> > + * i915_context_engines_bond:
> > + *
> > + * Constructed bonded pairs for execution within a virtual engine.
> > + *
> > + * All engines are equal, but some are more equal than others. Given
> > + * the distribution of resources in the HW, it may be preferable to run
> > + * a request on a given subset of engines in parallel to a request on a
> > + * specific engine. We enable this selection of engines within a virtual
> > + * engine by specifying bonding pairs, for any given master engine we will
> > + * only execute on one of the corresponding siblings within the virtual engine.
> > + *
> > + * To execute a request in parallel on the master engine and a sibling requires
> > + * coordination with a I915_EXEC_FENCE_SUBMIT.
> > + */
> > +struct i915_context_engines_bond {
> > + struct i915_user_extension base;
> > +
> > + __u16 virtual_index; /* index of virtual engine in ctx->engines[] */
> > + __u16 num_bonds;
> > +
> > + __u16 master_class;
> > + __u16 master_instance;
>
> struct i915_engine_class_instance master; ?
Yup, the oversight struck me when updating the igt.
-Chris
More information about the Intel-gfx
mailing list