Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/dma-buf/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  st-dma-resv.c   Sprache: C

 
/* SPDX-License-Identifier: MIT */

/*
* Copyright © 2019 Intel Corporation
* Copyright © 2021 Advanced Micro Devices, Inc.
*/


#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/dma-resv.h>

#include "selftest.h"

static struct spinlock fence_lock;

static const char *fence_name(struct dma_fence *f)
{
 return "selftest";
}

static const struct dma_fence_ops fence_ops = {
 .get_driver_name = fence_name,
 .get_timeline_name = fence_name,
};

static struct dma_fence *alloc_fence(void)
{
 struct dma_fence *f;

 f = kmalloc(sizeof(*f), GFP_KERNEL);
 if (!f)
  return NULL;

 dma_fence_init(f, &fence_ops, &fence_lock, 0, 0);
 return f;
}

static int sanitycheck(void *arg)
{
 struct dma_resv resv;
 struct dma_fence *f;
 int r;

 f = alloc_fence();
 if (!f)
  return -ENOMEM;

 dma_fence_enable_sw_signaling(f);

 dma_fence_signal(f);
 dma_fence_put(f);

 dma_resv_init(&resv);
 r = dma_resv_lock(&resv, NULL);
 if (r)
  pr_err("Resv locking failed\n");
 else
  dma_resv_unlock(&resv);
 dma_resv_fini(&resv);
 return r;
}

static int test_signaling(void *arg)
{
 enum dma_resv_usage usage = (unsigned long)arg;
 struct dma_resv resv;
 struct dma_fence *f;
 int r;

 f = alloc_fence();
 if (!f)
  return -ENOMEM;

 dma_fence_enable_sw_signaling(f);

 dma_resv_init(&resv);
 r = dma_resv_lock(&resv, NULL);
 if (r) {
  pr_err("Resv locking failed\n");
  goto err_free;
 }

 r = dma_resv_reserve_fences(&resv, 1);
 if (r) {
  pr_err("Resv shared slot allocation failed\n");
  goto err_unlock;
 }

 dma_resv_add_fence(&resv, f, usage);
 if (dma_resv_test_signaled(&resv, usage)) {
  pr_err("Resv unexpectedly signaled\n");
  r = -EINVAL;
  goto err_unlock;
 }
 dma_fence_signal(f);
 if (!dma_resv_test_signaled(&resv, usage)) {
  pr_err("Resv not reporting signaled\n");
  r = -EINVAL;
  goto err_unlock;
 }
err_unlock:
 dma_resv_unlock(&resv);
err_free:
 dma_resv_fini(&resv);
 dma_fence_put(f);
 return r;
}

static int test_for_each(void *arg)
{
 enum dma_resv_usage usage = (unsigned long)arg;
 struct dma_resv_iter cursor;
 struct dma_fence *f, *fence;
 struct dma_resv resv;
 int r;

 f = alloc_fence();
 if (!f)
  return -ENOMEM;

 dma_fence_enable_sw_signaling(f);

 dma_resv_init(&resv);
 r = dma_resv_lock(&resv, NULL);
 if (r) {
  pr_err("Resv locking failed\n");
  goto err_free;
 }

 r = dma_resv_reserve_fences(&resv, 1);
 if (r) {
  pr_err("Resv shared slot allocation failed\n");
  goto err_unlock;
 }

 dma_resv_add_fence(&resv, f, usage);

 r = -ENOENT;
 dma_resv_for_each_fence(&cursor, &resv, usage, fence) {
  if (!r) {
   pr_err("More than one fence found\n");
   r = -EINVAL;
   goto err_unlock;
  }
  if (f != fence) {
   pr_err("Unexpected fence\n");
   r = -EINVAL;
   goto err_unlock;
  }
  if (dma_resv_iter_usage(&cursor) != usage) {
   pr_err("Unexpected fence usage\n");
   r = -EINVAL;
   goto err_unlock;
  }
  r = 0;
 }
 if (r) {
  pr_err("No fence found\n");
  goto err_unlock;
 }
 dma_fence_signal(f);
err_unlock:
 dma_resv_unlock(&resv);
err_free:
 dma_resv_fini(&resv);
 dma_fence_put(f);
 return r;
}

static int test_for_each_unlocked(void *arg)
{
 enum dma_resv_usage usage = (unsigned long)arg;
 struct dma_resv_iter cursor;
 struct dma_fence *f, *fence;
 struct dma_resv resv;
 int r;

 f = alloc_fence();
 if (!f)
  return -ENOMEM;

 dma_fence_enable_sw_signaling(f);

 dma_resv_init(&resv);
 r = dma_resv_lock(&resv, NULL);
 if (r) {
  pr_err("Resv locking failed\n");
  goto err_free;
 }

 r = dma_resv_reserve_fences(&resv, 1);
 if (r) {
  pr_err("Resv shared slot allocation failed\n");
  dma_resv_unlock(&resv);
  goto err_free;
 }

 dma_resv_add_fence(&resv, f, usage);
 dma_resv_unlock(&resv);

 r = -ENOENT;
 dma_resv_iter_begin(&cursor, &resv, usage);
 dma_resv_for_each_fence_unlocked(&cursor, fence) {
  if (!r) {
   pr_err("More than one fence found\n");
   r = -EINVAL;
   goto err_iter_end;
  }
  if (!dma_resv_iter_is_restarted(&cursor)) {
   pr_err("No restart flag\n");
   goto err_iter_end;
  }
  if (f != fence) {
   pr_err("Unexpected fence\n");
   r = -EINVAL;
   goto err_iter_end;
  }
  if (dma_resv_iter_usage(&cursor) != usage) {
   pr_err("Unexpected fence usage\n");
   r = -EINVAL;
   goto err_iter_end;
  }

  /* We use r as state here */
  if (r == -ENOENT) {
   r = -EINVAL;
   /* That should trigger an restart */
   cursor.fences = (void*)~0;
  } else if (r == -EINVAL) {
   r = 0;
  }
 }
 if (r)
  pr_err("No fence found\n");
err_iter_end:
 dma_resv_iter_end(&cursor);
 dma_fence_signal(f);
err_free:
 dma_resv_fini(&resv);
 dma_fence_put(f);
 return r;
}

static int test_get_fences(void *arg)
{
 enum dma_resv_usage usage = (unsigned long)arg;
 struct dma_fence *f, **fences = NULL;
 struct dma_resv resv;
 int r, i;

 f = alloc_fence();
 if (!f)
  return -ENOMEM;

 dma_fence_enable_sw_signaling(f);

 dma_resv_init(&resv);
 r = dma_resv_lock(&resv, NULL);
 if (r) {
  pr_err("Resv locking failed\n");
  goto err_resv;
 }

 r = dma_resv_reserve_fences(&resv, 1);
 if (r) {
  pr_err("Resv shared slot allocation failed\n");
  dma_resv_unlock(&resv);
  goto err_resv;
 }

 dma_resv_add_fence(&resv, f, usage);
 dma_resv_unlock(&resv);

 r = dma_resv_get_fences(&resv, usage, &i, &fences);
 if (r) {
  pr_err("get_fences failed\n");
  goto err_free;
 }

 if (i != 1 || fences[0] != f) {
  pr_err("get_fences returned unexpected fence\n");
  goto err_free;
 }

 dma_fence_signal(f);
err_free:
 while (i--)
  dma_fence_put(fences[i]);
 kfree(fences);
err_resv:
 dma_resv_fini(&resv);
 dma_fence_put(f);
 return r;
}

int dma_resv(void)
{
 static const struct subtest tests[] = {
  SUBTEST(sanitycheck),
  SUBTEST(test_signaling),
  SUBTEST(test_for_each),
  SUBTEST(test_for_each_unlocked),
  SUBTEST(test_get_fences),
 };
 enum dma_resv_usage usage;
 int r;

 spin_lock_init(&fence_lock);
 for (usage = DMA_RESV_USAGE_KERNEL; usage <= DMA_RESV_USAGE_BOOKKEEP;
      ++usage) {
  r = subtests(tests, (void *)(unsigned long)usage);
  if (r)
   return r;
 }
 return 0;
}

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.2 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.