Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Karolina Stolarek <karolina.stolarek@intel.com>
To: "Zbigniew Kempczyński" <zbigniew.kempczynski@intel.com>
Cc: igt-dev@lists.freedesktop.org
Subject: Re: [igt-dev] [PATCH i-g-t v2 11/16] lib/intel_ctx: Add xe context information
Date: Tue, 11 Jul 2023 12:38:35 +0200	[thread overview]
Message-ID: <3a65db76-ab0b-0a4d-1a5a-59d7f001967e@intel.com> (raw)
In-Reply-To: <20230711090632.yrmouv5ajsjhdjrs@zkempczy-mobl2>

On 11.07.2023 11:06, Zbigniew Kempczyński wrote:
> On Fri, Jul 07, 2023 at 10:31:19AM +0200, Karolina Stolarek wrote:
>> On 6.07.2023 08:05, Zbigniew Kempczyński wrote:
>>> Most complicated part in adopting i915_blt to intel_blt - which should
>>> handle both drivers - is how to achieve pipelined execution. In term
>>> pipelined execution I mean all gpu workloads are executed without
>>> stalls.
>>>
>>> Comparing to i915 relocations and softpinning xe architecture migrates
>>> binding (this means also unbind operation) responsibility from the
>>> kernel to user via vm_bind ioctl(). To avoid stalls user has to
>>> provide in/out fences (syncobjs) between consecutive bindings/execs.
>>> Of course for many igt tests we don't need pipelined execution,
>>> just synchronous bind, then exec. But exercising the driver should
>>> also cover pipelining to verify it is possible to work without stalls.
>>>
>>> I decided to extend intel_ctx_t with all necessary for xe objects
>>> (vm, engine, syncobjs) to get flexibility in deciding how to bind,
>>> execute and wait for (synchronize) those operations. Context object
>>> along with i915 engine is already passed to blitter library so adding
>>> xe required fields doesn't break i915 but will allow xe path to get
>>> all necessary data to execute.
>>>
>>> Using intel_ctx with xe requires some code patterns caused by usage
>>> of an allocator. For xe the allocator started tracking alloc()/free()
>>> operations to do bind/unbind in one call just before execution.
>>> I've added two helpers in intel_ctx which - intel_ctx_xe_exec()
>>> and intel_ctx_xe_sync(). Depending how intel_ctx was created
>>> (with 0 or real syncobj handles as in/bind/out fences) bind and exec
>>> in intel_ctx_xe_exec() are pipelined but synchronize last operation
>>> (exec). For real syncobjs they are used to join bind + exec calls
>>> but there's no wait for exec (sync-out) completion. This allows
>>> building more cascaded bind + exec operations without stalls.
>>>
>>> To wait for a sync-out fence caller may use intel_ctx_xe_sync()
>>> which is synchronous wait on syncobj. It allows user to reset
>>> fences to prepare for next operation.
>>>
>>> Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
>>> ---
>>>    lib/intel_ctx.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++-
>>>    lib/intel_ctx.h |  14 ++++++
>>>    2 files changed, 123 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/lib/intel_ctx.c b/lib/intel_ctx.c
>>> index ded9c0f1e4..f210907fac 100644
>>> --- a/lib/intel_ctx.c
>>> +++ b/lib/intel_ctx.c
>>> @@ -5,9 +5,12 @@
>>>    #include <stddef.h>
>>> +#include "i915/gem_engine_topology.h"
>>> +#include "igt_syncobj.h"
>>> +#include "intel_allocator.h"
>>>    #include "intel_ctx.h"
>>>    #include "ioctl_wrappers.h"
>>> -#include "i915/gem_engine_topology.h"
>>> +#include "xe/xe_ioctl.h"
>>>    /**
>>>     * SECTION:intel_ctx
>>> @@ -390,3 +393,108 @@ unsigned int intel_ctx_engine_class(const intel_ctx_t *ctx, unsigned int engine)
>>>    {
>>>    	return intel_ctx_cfg_engine_class(&ctx->cfg, engine);
>>>    }
>>> +
>>> +/**
>>> + * intel_ctx_xe:
>>> + * @fd: open i915 drm file descriptor
>>> + * @vm: vm
>>> + * @engine: engine
>>> + *
>>> + * Returns an intel_ctx_t representing the xe context.
>>> + */
>>> +intel_ctx_t *intel_ctx_xe(int fd, uint32_t vm, uint32_t engine,
>>> +			  uint32_t sync_in, uint32_t sync_bind, uint32_t sync_out)
>>> +{
>>> +	intel_ctx_t *ctx;
>>> +
>>> +	ctx = calloc(1, sizeof(*ctx));
>>> +	igt_assert(ctx);
>>> +
>>> +	ctx->fd = fd;
>>> +	ctx->vm = vm;
>>> +	ctx->engine = engine;
>>> +	ctx->sync_in = sync_in;
>>> +	ctx->sync_bind = sync_bind;
>>> +	ctx->sync_out = sync_out;
>>> +
>>> +	return ctx;
>>> +}
>>> +
>>> +static int __xe_exec(int fd, struct drm_xe_exec *exec)
>>> +{
>>> +	int err = 0;
>>> +
>>> +	if (igt_ioctl(fd, DRM_IOCTL_XE_EXEC, exec)) {
>>> +		err = -errno;
>>> +		igt_assume(err != 0);
>>
>> Wouldn't "igt_assume(err)" be enough?
>>
>>> +	}
>>> +	errno = 0;
>>> +	return err;
>>> +}
>>
>> I'm aware that it's a helper that you use in other execs, but it feels out
>> of place, it doesn't deal with intel_ctx_t. Maybe xe_util could be its new
>> home?
>>
> 
> I'm going to just export __xe_exec() from xe_ioctl.c.

That's even a better idea, thanks

> 
>>> +
>>> +int __intel_ctx_xe_exec(const intel_ctx_t *ctx, uint64_t ahnd, uint64_t bb_offset)
>>> +{
>>> +	struct drm_xe_sync syncs[2] = {
>>> +		{ .flags = DRM_XE_SYNC_SYNCOBJ, },
>>> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
>>> +	};
>>> +	struct drm_xe_exec exec = {
>>> +		.engine_id = ctx->engine,
>>> +		.syncs = (uintptr_t)syncs,
>>> +		.num_syncs = 2,
>>> +		.address = bb_offset,
>>> +		.num_batch_buffer = 1,
>>> +	};
>>> +	uint32_t sync_in = ctx->sync_in;
>>> +	uint32_t sync_bind = ctx->sync_bind ?: syncobj_create(ctx->fd, 0);
>>> +	uint32_t sync_out = ctx->sync_out ?: syncobj_create(ctx->fd, 0);
>>> +	int ret;
>>> +
>>> +	/* Synchronize allocator state -> vm */
>>> +	intel_allocator_bind(ahnd, sync_in, sync_bind);
>>> +
>>> +	/* Pipelined exec */
>>> +	syncs[0].handle = sync_bind;
>>> +	syncs[1].handle = sync_out;
>>> +
>>> +	ret = __xe_exec(ctx->fd, &exec);
>>> +	if (ret)
>>> +		goto err;
>>> +
>>> +	if (!ctx->sync_bind || !ctx->sync_out)
>>> +		syncobj_wait_err(ctx->fd, &sync_out, 1, INT64_MAX, 0);
>>
>> This whole flow is so nice and tidy, I like it
>>
>>> +
>>> +err:
>>> +	if (!ctx->sync_bind)
>>> +		syncobj_destroy(ctx->fd, sync_bind);
>>> +
>>> +	if (!ctx->sync_out)
>>> +		syncobj_destroy(ctx->fd, sync_out);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +void intel_ctx_xe_exec(const intel_ctx_t *ctx, uint64_t ahnd, uint64_t bb_offset)
>>> +{
>>> +	igt_assert_eq(__intel_ctx_xe_exec(ctx, ahnd, bb_offset), 0);
>>> +}
>>> +
>>> +#define RESET_SYNCOBJ(__fd, __sync) do { \
>>> +	if (__sync) \
>>> +		syncobj_reset((__fd), &(__sync), 1); \
>>> +} while (0)
>>> +
>>> +int intel_ctx_xe_sync(intel_ctx_t *ctx, bool reset_syncs)
>>> +{
>>> +	int ret;
>>> +
>>> +	ret = syncobj_wait_err(ctx->fd, &ctx->sync_out, 1, INT64_MAX, 0);
>>> +
>>> +	if (reset_syncs) {
>>> +		RESET_SYNCOBJ(ctx->fd, ctx->sync_in);
>>> +		RESET_SYNCOBJ(ctx->fd, ctx->sync_bind);
>>> +		RESET_SYNCOBJ(ctx->fd, ctx->sync_out);
>>> +	}
>>
>> Is there a usecase where we want to do a synced execution without resetting
>> syncobjs?
>>
> 
> I don't know - that's I left decision to the user.

:) If there won't be a client for this functionality, we could drop it 
in the future

> 
>>> +
>>> +	return ret;
>>> +}
>>> diff --git a/lib/intel_ctx.h b/lib/intel_ctx.h
>>> index 3cfeaae81e..59d0360ada 100644
>>> --- a/lib/intel_ctx.h
>>> +++ b/lib/intel_ctx.h
>>> @@ -67,6 +67,14 @@ int intel_ctx_cfg_engine_class(const intel_ctx_cfg_t *cfg, unsigned int engine);
>>>    typedef struct intel_ctx {
>>>    	uint32_t id;
>>>    	intel_ctx_cfg_t cfg;
>>> +
>>> +	/* Xe */
>>> +	int fd;
>>> +	uint32_t vm;
>>> +	uint32_t engine;
>>> +	uint32_t sync_in;
>>> +	uint32_t sync_bind;
>>> +	uint32_t sync_out;
>>
>> Hmm, I wonder if we could wrap it in a struct. Yes, it would be painful to
>> unpack, but now it feels like we've just added a bunch of fields that are
>> irrelevant 80% of the time. Instead, we could have one additional field that
>> could be NULL, and use it if it's initialized.
>> But maybe I'm just being too nit-picky.
> 
> I wondered to introduce union of i915 and xe structs, but I would need
> to rewrite almost all igt's which are using this struct so I dropped
> this idea. At the moment I need to handle both drivers so mixing
> fields is not a big pain imo.

Oh my, that would be painful indeed. I mean, I won't nack the mixed 
fields, but I just find it strange to leave them in the open when we're 
testing i915 stuff.

All the best,
Karolina

> 
> --
> Zbigniew
> 
>>
>> All the best,
>> Karolina
>>
>>>    } intel_ctx_t;
>>>    int __intel_ctx_create(int fd, const intel_ctx_cfg_t *cfg,
>>> @@ -81,4 +89,10 @@ void intel_ctx_destroy(int fd, const intel_ctx_t *ctx);
>>>    unsigned int intel_ctx_engine_class(const intel_ctx_t *ctx, unsigned int engine);
>>> +intel_ctx_t *intel_ctx_xe(int fd, uint32_t vm, uint32_t engine,
>>> +			  uint32_t sync_in, uint32_t sync_bind, uint32_t sync_out);
>>> +int __intel_ctx_xe_exec(const intel_ctx_t *ctx, uint64_t ahnd, uint64_t bb_offset);
>>> +void intel_ctx_xe_exec(const intel_ctx_t *ctx, uint64_t ahnd, uint64_t bb_offset);
>>> +int intel_ctx_xe_sync(intel_ctx_t *ctx, bool reset_syncs);
>>> +
>>>    #endif

  reply	other threads:[~2023-07-11 10:38 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-06  6:05 [igt-dev] [PATCH i-g-t v2 00/16] Extend intel_blt to work on Xe Zbigniew Kempczyński
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 01/16] tests/api_intel_allocator: Don't use allocator ahnd aliasing api Zbigniew Kempczyński
2023-07-06  9:04   ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 02/16] lib/intel_allocator: Drop aliasing allocator handle api Zbigniew Kempczyński
2023-07-06  8:31   ` Karolina Stolarek
2023-07-06 11:20     ` Zbigniew Kempczyński
2023-07-06 13:28       ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 03/16] lib/intel_allocator: Remove extensive debugging Zbigniew Kempczyński
2023-07-06  9:30   ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 04/16] lib/xe_query: Use vramN when returning string region name Zbigniew Kempczyński
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 05/16] lib/xe_query: Add xe_region_class() helper Zbigniew Kempczyński
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 06/16] lib/drmtest: Add get_intel_driver() helper Zbigniew Kempczyński
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 07/16] lib/xe_util: Return dynamic subtest name for Xe Zbigniew Kempczyński
2023-07-06  9:37   ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 08/16] lib/xe_util: Add vm bind/unbind helper " Zbigniew Kempczyński
2023-07-06 10:27   ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 09/16] lib/intel_allocator: Add field to distinquish underlying driver Zbigniew Kempczyński
2023-07-06 10:34   ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 10/16] lib/intel_allocator: Add intel_allocator_bind() Zbigniew Kempczyński
2023-07-06 13:02   ` Karolina Stolarek
2023-07-06 16:09     ` Zbigniew Kempczyński
2023-07-07  8:01       ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 11/16] lib/intel_ctx: Add xe context information Zbigniew Kempczyński
2023-07-07  8:31   ` Karolina Stolarek
2023-07-11  9:06     ` Zbigniew Kempczyński
2023-07-11 10:38       ` Karolina Stolarek [this message]
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 12/16] lib/intel_blt: Introduce blt_copy_init() helper to cache driver Zbigniew Kempczyński
2023-07-07  8:51   ` Karolina Stolarek
2023-07-11  9:23     ` Zbigniew Kempczyński
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 13/16] lib/intel_blt: Extend blitter library to support xe driver Zbigniew Kempczyński
2023-07-07  9:26   ` Karolina Stolarek
2023-07-11 10:16     ` Zbigniew Kempczyński
2023-07-11 10:41       ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 14/16] tests/xe_ccs: Check if flatccs is working with block-copy for Xe Zbigniew Kempczyński
2023-07-07 10:05   ` Karolina Stolarek
2023-07-11 10:45     ` Zbigniew Kempczyński
2023-07-11 10:51       ` Karolina Stolarek
2023-07-12  7:00         ` Zbigniew Kempczyński
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 15/16] tests/xe_exercise_blt: Check blitter library fast-copy " Zbigniew Kempczyński
2023-07-07 11:10   ` Karolina Stolarek
2023-07-11 11:07     ` Zbigniew Kempczyński
2023-07-11 11:15       ` Karolina Stolarek
2023-07-06  6:05 ` [igt-dev] [PATCH i-g-t v2 16/16] tests/api-intel-allocator: Adopt to exercise allocator to Xe Zbigniew Kempczyński
2023-07-07 10:11   ` Karolina Stolarek
2023-07-06  6:58 ` [igt-dev] ✓ Fi.CI.BAT: success for Extend intel_blt to work on Xe (rev2) Patchwork
2023-07-06  9:26 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3a65db76-ab0b-0a4d-1a5a-59d7f001967e@intel.com \
    --to=karolina.stolarek@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=zbigniew.kempczynski@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox