Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/xe/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  xe_range_fence.c   Sprache: C

 
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */


#include <linux/dma-fence.h>
#include <linux/interval_tree_generic.h>
#include <linux/slab.h>

#include "xe_macros.h"
#include "xe_range_fence.h"

#define XE_RANGE_TREE_START(_node) ((_node)->start)
#define XE_RANGE_TREE_LAST(_node) ((_node)->last)

INTERVAL_TREE_DEFINE(struct xe_range_fence, rb, u64, __subtree_last,
       XE_RANGE_TREE_START, XE_RANGE_TREE_LAST, static,
       xe_range_fence_tree);

static void
xe_range_fence_signal_notify(struct dma_fence *fence, struct dma_fence_cb *cb)
{
 struct xe_range_fence *rfence = container_of(cb, typeof(*rfence), cb);
 struct xe_range_fence_tree *tree = rfence->tree;

 llist_add(&rfence->link, &tree->list);
}

static bool __xe_range_fence_tree_cleanup(struct xe_range_fence_tree *tree)
{
 struct llist_node *node = llist_del_all(&tree->list);
 struct xe_range_fence *rfence, *next;

 llist_for_each_entry_safe(rfence, next, node, link) {
  xe_range_fence_tree_remove(rfence, &tree->root);
  dma_fence_put(rfence->fence);
  kfree(rfence);
 }

 return !!node;
}

/**
 * xe_range_fence_insert() - range fence insert
 * @tree: range fence tree to insert intoi
 * @rfence: range fence
 * @ops: range fence ops
 * @start: start address of range fence
 * @last: last address of range fence
 * @fence: dma fence which signals range fence can be removed + freed
 *
 * Return: 0 on success, non-zero on failure
 */

int xe_range_fence_insert(struct xe_range_fence_tree *tree,
     struct xe_range_fence *rfence,
     const struct xe_range_fence_ops *ops,
     u64 start, u64 last, struct dma_fence *fence)
{
 int err = 0;

 __xe_range_fence_tree_cleanup(tree);

 if (dma_fence_is_signaled(fence))
  goto free;

 rfence->ops = ops;
 rfence->start = start;
 rfence->last = last;
 rfence->tree = tree;
 rfence->fence = dma_fence_get(fence);
 err = dma_fence_add_callback(fence, &rfence->cb,
         xe_range_fence_signal_notify);
 if (err == -ENOENT) {
  dma_fence_put(fence);
  err = 0;
  goto free;
 } else if (err == 0) {
  xe_range_fence_tree_insert(rfence, &tree->root);
  return 0;
 }

free:
 if (ops->free)
  ops->free(rfence);

 return err;
}

static void xe_range_fence_tree_remove_all(struct xe_range_fence_tree *tree)
{
 struct xe_range_fence *rfence;
 bool retry = true;

 rfence = xe_range_fence_tree_iter_first(&tree->root, 0, U64_MAX);
 while (rfence) {
  /* Should be ok with the minimalistic callback */
  if (dma_fence_remove_callback(rfence->fence, &rfence->cb))
   llist_add(&rfence->link, &tree->list);
  rfence = xe_range_fence_tree_iter_next(rfence, 0, U64_MAX);
 }

 while (retry)
  retry = __xe_range_fence_tree_cleanup(tree);
}

/**
 * xe_range_fence_tree_init() - Init range fence tree
 * @tree: range fence tree
 */

void xe_range_fence_tree_init(struct xe_range_fence_tree *tree)
{
 memset(tree, 0, sizeof(*tree));
}

/**
 * xe_range_fence_tree_fini() - Fini range fence tree
 * @tree: range fence tree
 */

void xe_range_fence_tree_fini(struct xe_range_fence_tree *tree)
{
 xe_range_fence_tree_remove_all(tree);
 XE_WARN_ON(!RB_EMPTY_ROOT(&tree->root.rb_root));
}

/**
 * xe_range_fence_tree_first() - range fence tree iterator first
 * @tree: range fence tree
 * @start: start address of range fence
 * @last: last address of range fence
 *
 * Return: first range fence found in range or NULL
 */

struct xe_range_fence *
xe_range_fence_tree_first(struct xe_range_fence_tree *tree, u64 start,
     u64 last)
{
 return xe_range_fence_tree_iter_first(&tree->root, start, last);
}

/**
 * xe_range_fence_tree_next() - range fence tree iterator next
 * @rfence: current range fence
 * @start: start address of range fence
 * @last: last address of range fence
 *
 * Return: next range fence found in range or NULL
 */

struct xe_range_fence *
xe_range_fence_tree_next(struct xe_range_fence *rfence, u64 start, u64 last)
{
 return xe_range_fence_tree_iter_next(rfence, start, last);
}

static void xe_range_fence_free(struct xe_range_fence *rfence)
{
 kfree(rfence);
}

const struct xe_range_fence_ops xe_range_fence_kfree_ops = {
 .free = xe_range_fence_free,
};

Messung V0.5
C=96 H=88 G=91

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© 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.