All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fabiano Rosas <farosas@suse.de>
To: "Yichen Wang" <yichen.wang@bytedance.com>,
	"Peter Xu" <peterx@redhat.com>,
	"Dr. David Alan Gilbert" <dave@treblig.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Eric Blake" <eblake@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Cornelia Huck" <cohuck@redhat.com>,
	qemu-devel@nongnu.org
Cc: Hao Xiang <hao.xiang@linux.dev>,
	"Liu, Yuan1" <yuan1.liu@intel.com>,
	Shivam Kumar <shivam.kumar1@nutanix.com>,
	"Ho-Ren (Jack) Chuang" <horenchuang@bytedance.com>,
	Yichen Wang <yichen.wang@bytedance.com>,
	Bryan Zhang <bryan.zhang@bytedance.com>
Subject: Re: [PATCH v7 06/12] util/dsa: Implement zero page checking in DSA task.
Date: Mon, 25 Nov 2024 12:53:29 -0300	[thread overview]
Message-ID: <875xobpax2.fsf@suse.de> (raw)
In-Reply-To: <20241114220132.27399-7-yichen.wang@bytedance.com>

Yichen Wang <yichen.wang@bytedance.com> writes:

> From: Hao Xiang <hao.xiang@linux.dev>
>
> Create DSA task with operation code DSA_OPCODE_COMPVAL.
> Here we create two types of DSA tasks, a single DSA task and
> a batch DSA task. Batch DSA task reduces task submission overhead
> and hence should be the default option. However, due to the way DSA
> hardware works, a DSA batch task must contain at least two individual
> tasks. There are times we need to submit a single task and hence a
> single DSA task submission is also required.
>
> Signed-off-by: Hao Xiang <hao.xiang@linux.dev>
> Signed-off-by: Bryan Zhang <bryan.zhang@bytedance.com>
> Signed-off-by: Yichen Wang <yichen.wang@bytedance.com>
> ---
>  include/qemu/dsa.h |  44 ++++++--
>  util/dsa.c         | 254 +++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 269 insertions(+), 29 deletions(-)
>
> diff --git a/include/qemu/dsa.h b/include/qemu/dsa.h
> index d24567f0be..cb407b8b49 100644
> --- a/include/qemu/dsa.h
> +++ b/include/qemu/dsa.h
> @@ -16,6 +16,7 @@
>  #define QEMU_DSA_H
>  
>  #include "qapi/error.h"
> +#include "exec/cpu-common.h"
>  #include "qemu/thread.h"
>  #include "qemu/queue.h"
>  
> @@ -70,10 +71,11 @@ typedef struct QemuDsaBatchTask {
>      QemuDsaTaskStatus status;
>      int batch_size;
>      bool *results;
> +    /* Address of each pages in pages */
> +    ram_addr_t *addr;
>      QSIMPLEQ_ENTRY(QemuDsaBatchTask) entry;
>  } QemuDsaBatchTask;
>  
> -
>  /**
>   * @brief Initializes DSA devices.
>   *
> @@ -105,8 +107,26 @@ void qemu_dsa_cleanup(void);
>   */
>  bool qemu_dsa_is_running(void);
>  
> +/**
> + * @brief Initializes a buffer zero DSA batch task.
> + *
> + * @param batch_size The number of zero page checking tasks in the batch.
> + * @return A pointer to the zero page checking tasks initialized.
> + */
> +QemuDsaBatchTask *
> +buffer_zero_batch_task_init(int batch_size);
> +
> +/**
> + * @brief Performs the proper cleanup on a DSA batch task.
> + *
> + * @param task A pointer to the batch task to cleanup.
> + */
> +void buffer_zero_batch_task_destroy(QemuDsaBatchTask *task);
> +
>  #else
>  
> +typedef struct QemuDsaBatchTask {} QemuDsaBatchTask;
> +
>  static inline bool qemu_dsa_is_running(void)
>  {
>      return false;
> @@ -114,19 +134,27 @@ static inline bool qemu_dsa_is_running(void)
>  
>  static inline int qemu_dsa_init(const strList *dsa_parameter, Error **errp)
>  {
> -    if (dsa_parameter != NULL && strlen(dsa_parameter) != 0) {
> -        error_setg(errp, "DSA is not supported.");
> -        return -1;
> -    }
> -
> -    return 0;
> +    error_setg(errp, "DSA accelerator is not enabled.");
> +    return -1;

This should have been fixed in the patch that introduced this function.

>  }
>  
>  static inline void qemu_dsa_start(void) {}
>  
>  static inline void qemu_dsa_stop(void) {}
>  
> -static inline void qemu_dsa_cleanup(void) {}

Where did this go?

> +static inline QemuDsaBatchTask *buffer_zero_batch_task_init(int batch_size)
> +{
> +    return NULL;
> +}
> +
> +static inline void buffer_zero_batch_task_destroy(QemuDsaBatchTask *task) {}
> +
> +static inline int
> +buffer_is_zero_dsa_batch_sync(QemuDsaBatchTask *batch_task,
> +                              const void **buf, size_t count, size_t len)
> +{
> +    return -1;
> +}
>  
>  #endif
>  
> diff --git a/util/dsa.c b/util/dsa.c
> index c3ca71df86..408c163195 100644
> --- a/util/dsa.c
> +++ b/util/dsa.c
> @@ -48,6 +48,7 @@ uint32_t max_retry_count;
>  static QemuDsaDeviceGroup dsa_group;
>  static QemuDsaCompletionThread completion_thread;
>  
> +static void buffer_zero_dsa_completion(void *context);
>  
>  /**
>   * @brief This function opens a DSA device's work queue and
> @@ -174,7 +175,6 @@ dsa_device_group_start(QemuDsaDeviceGroup *group)
>   *
>   * @param group A pointer to the DSA device group.
>   */
> -__attribute__((unused))
>  static void
>  dsa_device_group_stop(QemuDsaDeviceGroup *group)
>  {
> @@ -210,7 +210,6 @@ dsa_device_group_cleanup(QemuDsaDeviceGroup *group)
>   * @return struct QemuDsaDevice* A pointer to the next available DSA device
>   *         in the group.
>   */
> -__attribute__((unused))
>  static QemuDsaDevice *
>  dsa_device_group_get_next_device(QemuDsaDeviceGroup *group)
>  {
> @@ -283,7 +282,6 @@ dsa_task_enqueue(QemuDsaDeviceGroup *group,
>   * @param group A pointer to the DSA device group.
>   * @return QemuDsaBatchTask* The DSA task being dequeued.
>   */
> -__attribute__((unused))
>  static QemuDsaBatchTask *
>  dsa_task_dequeue(QemuDsaDeviceGroup *group)
>  {
> @@ -338,22 +336,6 @@ submit_wi_int(void *wq, struct dsa_hw_desc *descriptor)
>      return 0;
>  }
>  
> -/**
> - * @brief Synchronously submits a DSA work item to the
> - *        device work queue.
> - *
> - * @param wq A pointer to the DSA work queue's device memory.
> - * @param descriptor A pointer to the DSA work item descriptor.
> - *
> - * @return int Zero if successful, non-zero otherwise.
> - */
> -__attribute__((unused))
> -static int
> -submit_wi(void *wq, struct dsa_hw_desc *descriptor)
> -{
> -    return submit_wi_int(wq, descriptor);
> -}
> -

Why is this being removed?

>  /**
>   * @brief Asynchronously submits a DSA work item to the
>   *        device work queue.
> @@ -362,7 +344,6 @@ submit_wi(void *wq, struct dsa_hw_desc *descriptor)
>   *
>   * @return int Zero if successful, non-zero otherwise.
>   */
> -__attribute__((unused))
>  static int
>  submit_wi_async(QemuDsaBatchTask *task)
>  {
> @@ -391,7 +372,6 @@ submit_wi_async(QemuDsaBatchTask *task)
>   *
>   * @return int Zero if successful, non-zero otherwise.
>   */
> -__attribute__((unused))
>  static int
>  submit_batch_wi_async(QemuDsaBatchTask *batch_task)
>  {
> @@ -750,3 +730,235 @@ void qemu_dsa_cleanup(void)
>      dsa_device_group_cleanup(&dsa_group);
>  }
>  
> +
> +/* Buffer zero comparison DSA task implementations */
> +/* =============================================== */
> +
> +/**
> + * @brief Sets a buffer zero comparison DSA task.
> + *
> + * @param descriptor A pointer to the DSA task descriptor.
> + * @param buf A pointer to the memory buffer.
> + * @param len The length of the buffer.
> + */
> +static void
> +buffer_zero_task_set_int(struct dsa_hw_desc *descriptor,
> +                         const void *buf,
> +                         size_t len)
> +{
> +    struct dsa_completion_record *completion =
> +        (struct dsa_completion_record *)descriptor->completion_addr;
> +
> +    descriptor->xfer_size = len;
> +    descriptor->src_addr = (uintptr_t)buf;
> +    completion->status = 0;
> +    completion->result = 0;
> +}
> +
> +/**
> + * @brief Resets a buffer zero comparison DSA batch task.
> + *
> + * @param task A pointer to the DSA batch task.
> + */
> +static void
> +buffer_zero_task_reset(QemuDsaBatchTask *task)
> +{
> +    task->completions[0].status = DSA_COMP_NONE;
> +    task->task_type = QEMU_DSA_TASK;
> +    task->status = QEMU_DSA_TASK_READY;
> +}
> +
> +/**
> + * @brief Resets a buffer zero comparison DSA batch task.
> + *
> + * @param task A pointer to the batch task.
> + * @param count The number of DSA tasks this batch task will contain.
> + */
> +static void
> +buffer_zero_batch_task_reset(QemuDsaBatchTask *task, size_t count)
> +{
> +    task->batch_completion.status = DSA_COMP_NONE;
> +    task->batch_descriptor.desc_count = count;
> +    task->task_type = QEMU_DSA_BATCH_TASK;
> +    task->status = QEMU_DSA_TASK_READY;
> +}
> +
> +/**
> + * @brief Sets a buffer zero comparison DSA task.
> + *
> + * @param task A pointer to the DSA task.
> + * @param buf A pointer to the memory buffer.
> + * @param len The buffer length.
> + */
> +static void
> +buffer_zero_task_set(QemuDsaBatchTask *task,
> +                     const void *buf,
> +                     size_t len)
> +{
> +    buffer_zero_task_reset(task);
> +    buffer_zero_task_set_int(&task->descriptors[0], buf, len);
> +}
> +
> +/**
> + * @brief Sets a buffer zero comparison batch task.
> + *
> + * @param batch_task A pointer to the batch task.
> + * @param buf An array of memory buffers.
> + * @param count The number of buffers in the array.
> + * @param len The length of the buffers.
> + */
> +static void
> +buffer_zero_batch_task_set(QemuDsaBatchTask *batch_task,
> +                           const void **buf, size_t count, size_t len)
> +{
> +    assert(count > 0);
> +    assert(count <= batch_task->batch_size);
> +
> +    buffer_zero_batch_task_reset(batch_task, count);
> +    for (int i = 0; i < count; i++) {
> +        buffer_zero_task_set_int(&batch_task->descriptors[i], buf[i], len);
> +    }
> +}
> +
> +/**
> + * @brief Asychronously perform a buffer zero DSA operation.
> + *
> + * @param task A pointer to the batch task structure.
> + * @param buf A pointer to the memory buffer.
> + * @param len The length of the memory buffer.
> + *
> + * @return int Zero if successful, otherwise an appropriate error code.
> + */
> +__attribute__((unused))
> +static int
> +buffer_zero_dsa_async(QemuDsaBatchTask *task,
> +                      const void *buf, size_t len)
> +{
> +    buffer_zero_task_set(task, buf, len);
> +
> +    return submit_wi_async(task);
> +}
> +
> +/**
> + * @brief Sends a memory comparison batch task to a DSA device and wait
> + *        for completion.
> + *
> + * @param batch_task The batch task to be submitted to DSA device.
> + * @param buf An array of memory buffers to check for zero.
> + * @param count The number of buffers.
> + * @param len The buffer length.
> + */
> +__attribute__((unused))
> +static int
> +buffer_zero_dsa_batch_async(QemuDsaBatchTask *batch_task,
> +                            const void **buf, size_t count, size_t len)
> +{
> +    assert(count <= batch_task->batch_size);
> +    buffer_zero_batch_task_set(batch_task, buf, count, len);
> +
> +    return submit_batch_wi_async(batch_task);
> +}
> +
> +/**
> + * @brief The completion callback function for buffer zero
> + *        comparison DSA task completion.
> + *
> + * @param context A pointer to the callback context.
> + */
> +static void
> +buffer_zero_dsa_completion(void *context)
> +{
> +    assert(context != NULL);
> +
> +    QemuDsaBatchTask *task = (QemuDsaBatchTask *)context;
> +    qemu_sem_post(&task->sem_task_complete);
> +}
> +
> +/**
> + * @brief Wait for the asynchronous DSA task to complete.
> + *
> + * @param batch_task A pointer to the buffer zero comparison batch task.
> + */
> +__attribute__((unused))
> +static void
> +buffer_zero_dsa_wait(QemuDsaBatchTask *batch_task)
> +{
> +    qemu_sem_wait(&batch_task->sem_task_complete);
> +}
> +
> +/**
> + * @brief Initializes a buffer zero comparison DSA task.
> + *
> + * @param descriptor A pointer to the DSA task descriptor.
> + * @param completion A pointer to the DSA task completion record.
> + */
> +static void
> +buffer_zero_task_init_int(struct dsa_hw_desc *descriptor,
> +                          struct dsa_completion_record *completion)
> +{
> +    descriptor->opcode = DSA_OPCODE_COMPVAL;
> +    descriptor->flags = IDXD_OP_FLAG_RCR | IDXD_OP_FLAG_CRAV;
> +    descriptor->comp_pattern = (uint64_t)0;
> +    descriptor->completion_addr = (uint64_t)completion;
> +}
> +
> +/**
> + * @brief Initializes a buffer zero DSA batch task.
> + *
> + * @param batch_size The number of zero page checking tasks in the batch.
> + * @return A pointer to the zero page checking tasks initialized.
> + */
> +QemuDsaBatchTask *
> +buffer_zero_batch_task_init(int batch_size)
> +{
> +    QemuDsaBatchTask *task = qemu_memalign(64, sizeof(QemuDsaBatchTask));
> +    int descriptors_size = sizeof(*task->descriptors) * batch_size;
> +
> +    memset(task, 0, sizeof(*task));
> +    task->addr = g_new0(ram_addr_t, batch_size);
> +    task->results = g_new0(bool, batch_size);
> +    task->batch_size = batch_size;
> +    task->descriptors =
> +        (struct dsa_hw_desc *)qemu_memalign(64, descriptors_size);
> +    memset(task->descriptors, 0, descriptors_size);
> +    task->completions = (struct dsa_completion_record *)qemu_memalign(
> +        32, sizeof(*task->completions) * batch_size);
> +
> +    task->batch_completion.status = DSA_COMP_NONE;
> +    task->batch_descriptor.completion_addr = (uint64_t)&task->batch_completion;
> +    /* TODO: Ensure that we never send a batch with count <= 1 */
> +    task->batch_descriptor.desc_count = 0;
> +    task->batch_descriptor.opcode = DSA_OPCODE_BATCH;
> +    task->batch_descriptor.flags = IDXD_OP_FLAG_RCR | IDXD_OP_FLAG_CRAV;
> +    task->batch_descriptor.desc_list_addr = (uintptr_t)task->descriptors;
> +    task->status = QEMU_DSA_TASK_READY;
> +    task->group = &dsa_group;
> +    task->device = dsa_device_group_get_next_device(&dsa_group);
> +
> +    for (int i = 0; i < task->batch_size; i++) {
> +        buffer_zero_task_init_int(&task->descriptors[i],
> +                                  &task->completions[i]);
> +    }
> +
> +    qemu_sem_init(&task->sem_task_complete, 0);
> +    task->completion_callback = buffer_zero_dsa_completion;
> +
> +    return task;
> +}
> +
> +/**
> + * @brief Performs the proper cleanup on a DSA batch task.
> + *
> + * @param task A pointer to the batch task to cleanup.
> + */
> +void
> +buffer_zero_batch_task_destroy(QemuDsaBatchTask *task)
> +{
> +    g_free(task->addr);
> +    g_free(task->results);
> +    qemu_vfree(task->descriptors);
> +    qemu_vfree(task->completions);
> +    task->results = NULL;
> +    qemu_sem_destroy(&task->sem_task_complete);
> +    qemu_vfree(task);
> +}


  reply	other threads:[~2024-11-25 15:54 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-14 22:01 [PATCH v7 00/12] Use Intel DSA accelerator to offload zero page checking in multifd live migration Yichen Wang
2024-11-14 22:01 ` [PATCH v7 01/12] meson: Introduce new instruction set enqcmd to the build system Yichen Wang
2024-11-21 13:51   ` Fabiano Rosas
2024-11-14 22:01 ` [PATCH v7 02/12] util/dsa: Add idxd into linux header copy list Yichen Wang
2024-11-21 13:51   ` Fabiano Rosas
2024-11-14 22:01 ` [PATCH v7 03/12] util/dsa: Implement DSA device start and stop logic Yichen Wang
2024-11-21 14:11   ` Fabiano Rosas
2024-11-14 22:01 ` [PATCH v7 04/12] util/dsa: Implement DSA task enqueue and dequeue Yichen Wang
2024-11-21 20:55   ` Fabiano Rosas
2024-11-14 22:01 ` [PATCH v7 05/12] util/dsa: Implement DSA task asynchronous completion thread model Yichen Wang
2024-11-21 20:58   ` Fabiano Rosas
2024-11-14 22:01 ` [PATCH v7 06/12] util/dsa: Implement zero page checking in DSA task Yichen Wang
2024-11-25 15:53   ` Fabiano Rosas [this message]
2024-11-26  4:38     ` [External] " Yichen Wang
2024-11-14 22:01 ` [PATCH v7 07/12] util/dsa: Implement DSA task asynchronous submission and wait for completion Yichen Wang
2024-11-25 18:00   ` Fabiano Rosas
2024-11-14 22:01 ` [PATCH v7 08/12] migration/multifd: Add new migration option for multifd DSA offloading Yichen Wang
2024-11-15 14:32   ` Dr. David Alan Gilbert
2024-11-14 22:01 ` [PATCH v7 09/12] migration/multifd: Enable DSA offloading in multifd sender path Yichen Wang
2024-11-21 20:50   ` Fabiano Rosas
2024-11-26  4:41     ` [External] " Yichen Wang
2024-11-26 13:20       ` Fabiano Rosas
2024-12-03  3:43         ` Yichen Wang
2024-11-14 22:01 ` [PATCH v7 10/12] util/dsa: Add unit test coverage for Intel DSA task submission and completion Yichen Wang
2024-11-14 22:01 ` [PATCH v7 11/12] migration/multifd: Add integration tests for multifd with Intel DSA offloading Yichen Wang
2024-11-25 18:25   ` Fabiano Rosas
2024-11-14 22:01 ` [PATCH v7 12/12] migration/doc: Add DSA zero page detection doc Yichen Wang
2024-11-25 18:28   ` Fabiano Rosas
2024-11-19 21:31 ` [PATCH v7 00/12] Use Intel DSA accelerator to offload zero page checking in multifd live migration Fabiano Rosas
2024-11-26  4:43   ` [External] " Yichen Wang

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=875xobpax2.fsf@suse.de \
    --to=farosas@suse.de \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=bryan.zhang@bytedance.com \
    --cc=cohuck@redhat.com \
    --cc=dave@treblig.org \
    --cc=eblake@redhat.com \
    --cc=hao.xiang@linux.dev \
    --cc=horenchuang@bytedance.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=shivam.kumar1@nutanix.com \
    --cc=yichen.wang@bytedance.com \
    --cc=yuan1.liu@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.