All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
	"Matthew Auld" <matthew.auld@intel.com>,
	"Christian König" <christian.koenig@amd.com>
Subject: [RFC] Cross-driver ww transaction lock lists
Date: Tue, 13 Apr 2021 09:50:15 +0200	[thread overview]
Message-ID: <62e5b25ce7e22633c09fb0242a69d268b3b45595.camel@linux.intel.com> (raw)

Hi!

During the dma_resv conversion of the i915 driver, we've been using ww
transaction lock lists to keep track of ww_mutexes that are locked
during the transaction so that they can be batch unlocked at suitable
locations. Including also the LMEM/VRAM eviction we've ended up with
two static lists per transaction context; one typically unlocked at the
end of transaction and one initialized before and unlocked after each
buffer object validate. This enables us to do sleeping locking at
eviction and keep objects locked on the eviction list until we
eventually succeed allocating memory (modulo minor flaws of course).

It would be beneficial with the i915 TTM conversion to be able to
introduce a similar functionality that would work in ttm but also
cross-driver in, for example move_notify. It would also be beneficial
to be able to put any dma_resv ww mutex on the lists, and not require
it to be embedded in a particular object type.

I started scetching on some utilities for this. For TTM, for example,
the idea would be to pass a list head for the ww transaction lock list
in the ttm_operation_ctx. A function taking a ww_mutex could then
either attach a grabbed lock to the list for batch unlocking, or be
responsible for unlocking when the lock's scope is exited. It's also
possible to create sublists if so desired. I believe the below would be
sufficient to cover the i915 functionality.

Any comments and suggestions appreciated!

8<------------------------------------------------------

#ifndef _TRANSACTION_LOCKLIST_H_
#define _TRANSACTION_LOCKLIST_H_

struct trans_lockitem;

/**
 * struct trans_locklist_ops - Ops structure for the ww locklist
functionality.
 *
 * Typically a const struct trans_locklist_ops is defined for each type
that
 * embeds a struct trans_lockitem, or hav a struct trans_lockitem
pointing
 * at it using the private pointer. It can be a buffer object,
reservation
 * object, a single ww_mutex or even a sublist of trans_lockitems. 
 */
struct trans_locklist_ops {
	/**
	 * slow_lock: Slow lock to relax the transaction. Only used by
	 * a contending lock item.
	 * @item: The struct trans_lockitem to lock
	 * @intr: Whether to lock interruptible
	 *
	 * Return: -ERESTARTSYS: Hit a signal when relaxing,
	 * -EAGAIN, relaxing succesful, but the contending lock
	 * remains unlocked.
	 */
	int (*slow_lock) (struct trans_lockitem *item, bool intr);

	/**
	 * unlock: Unlock.
	 * @item: The struct trans_lockitem to unlock.
	 */
	void (*unlock) (struct trans_lockitem *item);

	/**
	 * unlock: Unlock.
	 * @item: The struct trans_lockitem to put. This function may
be NULL.
	 */
	void (*put) (struct trans_lockitem *item);
};

/**
 * struct trans_lockitem
 * @ops: Pointer to an Ops structure for this lockitem.
 * @link: List link for the transaction locklist.
 * @private: Private info.
 * @relax_unlock: Unlock contending lock after relaxation since it is
 * likely not needed after a transaction restart.
 *
 * A struct trans_lockitem typically represents a single lock, but is
 * generic enough to represent a sublist of locks. It can either be
 * embedded, or allocated on demand. A kmem_cache might be beneficial.
 */
struct trans_lockitem {
	const struct trans_locklist_ops *ops;
	struct list_head link;
	u32 relax_unlock:1;
	void *private;
};

/* unlock example */
static inline void trans_unlock_put_all(struct list_head *list)
{
	struct trans_lockitem *lock, *next;

	list_for_each_entry_safe(lock, next, typeof(*lock), link) {
		lock->ops->unlock(lock);
		list_del_init(&lock->link);
		if (lock->ops_put)
			lock->ops->put(lock);
	}
}

/* Backoff example */
static inline int __must_check trans_backoff(struct list_head *list,
bool intr,
					     struct trans_lockitem
*contending)
{
	int ret = 0;

	trans_unlock_put_all(list);
	if (contending) {
		ret = contending->ops->slow_lock(contending, intr);
		if (!ret && contending->relax_unlock)
			contending->unlock(contending);
		if (ret == -EAGAIN)
			ret = 0;
		contending->ops->put(contending);
	}

	return ret;
}
		
		
#endif _TRANSACTION_LOCKLIST_


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
	"Matthew Auld" <matthew.auld@intel.com>,
	"Christian König" <christian.koenig@amd.com>
Subject: [Intel-gfx] [RFC] Cross-driver ww transaction lock lists
Date: Tue, 13 Apr 2021 09:50:15 +0200	[thread overview]
Message-ID: <62e5b25ce7e22633c09fb0242a69d268b3b45595.camel@linux.intel.com> (raw)

Hi!

During the dma_resv conversion of the i915 driver, we've been using ww
transaction lock lists to keep track of ww_mutexes that are locked
during the transaction so that they can be batch unlocked at suitable
locations. Including also the LMEM/VRAM eviction we've ended up with
two static lists per transaction context; one typically unlocked at the
end of transaction and one initialized before and unlocked after each
buffer object validate. This enables us to do sleeping locking at
eviction and keep objects locked on the eviction list until we
eventually succeed allocating memory (modulo minor flaws of course).

It would be beneficial with the i915 TTM conversion to be able to
introduce a similar functionality that would work in ttm but also
cross-driver in, for example move_notify. It would also be beneficial
to be able to put any dma_resv ww mutex on the lists, and not require
it to be embedded in a particular object type.

I started scetching on some utilities for this. For TTM, for example,
the idea would be to pass a list head for the ww transaction lock list
in the ttm_operation_ctx. A function taking a ww_mutex could then
either attach a grabbed lock to the list for batch unlocking, or be
responsible for unlocking when the lock's scope is exited. It's also
possible to create sublists if so desired. I believe the below would be
sufficient to cover the i915 functionality.

Any comments and suggestions appreciated!

8<------------------------------------------------------

#ifndef _TRANSACTION_LOCKLIST_H_
#define _TRANSACTION_LOCKLIST_H_

struct trans_lockitem;

/**
 * struct trans_locklist_ops - Ops structure for the ww locklist
functionality.
 *
 * Typically a const struct trans_locklist_ops is defined for each type
that
 * embeds a struct trans_lockitem, or hav a struct trans_lockitem
pointing
 * at it using the private pointer. It can be a buffer object,
reservation
 * object, a single ww_mutex or even a sublist of trans_lockitems. 
 */
struct trans_locklist_ops {
	/**
	 * slow_lock: Slow lock to relax the transaction. Only used by
	 * a contending lock item.
	 * @item: The struct trans_lockitem to lock
	 * @intr: Whether to lock interruptible
	 *
	 * Return: -ERESTARTSYS: Hit a signal when relaxing,
	 * -EAGAIN, relaxing succesful, but the contending lock
	 * remains unlocked.
	 */
	int (*slow_lock) (struct trans_lockitem *item, bool intr);

	/**
	 * unlock: Unlock.
	 * @item: The struct trans_lockitem to unlock.
	 */
	void (*unlock) (struct trans_lockitem *item);

	/**
	 * unlock: Unlock.
	 * @item: The struct trans_lockitem to put. This function may
be NULL.
	 */
	void (*put) (struct trans_lockitem *item);
};

/**
 * struct trans_lockitem
 * @ops: Pointer to an Ops structure for this lockitem.
 * @link: List link for the transaction locklist.
 * @private: Private info.
 * @relax_unlock: Unlock contending lock after relaxation since it is
 * likely not needed after a transaction restart.
 *
 * A struct trans_lockitem typically represents a single lock, but is
 * generic enough to represent a sublist of locks. It can either be
 * embedded, or allocated on demand. A kmem_cache might be beneficial.
 */
struct trans_lockitem {
	const struct trans_locklist_ops *ops;
	struct list_head link;
	u32 relax_unlock:1;
	void *private;
};

/* unlock example */
static inline void trans_unlock_put_all(struct list_head *list)
{
	struct trans_lockitem *lock, *next;

	list_for_each_entry_safe(lock, next, typeof(*lock), link) {
		lock->ops->unlock(lock);
		list_del_init(&lock->link);
		if (lock->ops_put)
			lock->ops->put(lock);
	}
}

/* Backoff example */
static inline int __must_check trans_backoff(struct list_head *list,
bool intr,
					     struct trans_lockitem
*contending)
{
	int ret = 0;

	trans_unlock_put_all(list);
	if (contending) {
		ret = contending->ops->slow_lock(contending, intr);
		if (!ret && contending->relax_unlock)
			contending->unlock(contending);
		if (ret == -EAGAIN)
			ret = 0;
		contending->ops->put(contending);
	}

	return ret;
}
		
		
#endif _TRANSACTION_LOCKLIST_


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

             reply	other threads:[~2021-04-13  7:50 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-13  7:50 Thomas Hellström [this message]
2021-04-13  7:50 ` [Intel-gfx] [RFC] Cross-driver ww transaction lock lists Thomas Hellström
2021-04-13  7:57 ` Christian König
2021-04-13  7:57   ` [Intel-gfx] " Christian König
2021-04-13  8:07   ` Thomas Hellström (Intel)
2021-04-15 13:37   ` Daniel Vetter
2021-04-15 13:37     ` [Intel-gfx] " Daniel Vetter
2021-04-15 14:02     ` [Linaro-mm-sig] " Thomas Hellström (Intel)
2021-04-15 14:02       ` [Intel-gfx] " Thomas Hellström (Intel)
2021-04-15 14:40       ` Daniel Vetter
2021-04-15 14:40         ` [Intel-gfx] " Daniel Vetter
2021-04-15 15:40         ` Thomas Hellström (Intel)
2021-04-15 15:40           ` [Intel-gfx] " Thomas Hellström (Intel)
2021-04-15 15:51           ` Daniel Vetter
2021-04-15 15:51             ` [Intel-gfx] " Daniel Vetter

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=62e5b25ce7e22633c09fb0242a69d268b3b45595.camel@linux.intel.com \
    --to=thomas.hellstrom@linux.intel.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=matthew.auld@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.