All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: linux-kernel@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org,
	Chris Wilson <chris@chris-wilson.co.uk>,
	Sumit Semwal <sumit.semwal@linaro.org>,
	Shuah Khan <shuahkh@osg.samsung.com>, Tejun Heo <tj@kernel.org>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Andrew Morton <akpm@linux-foundation.org>,
	Ingo Molnar <mingo@kernel.org>, Kees Cook <keescook@chromium.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Andrey Ryabinin <aryabinin@virtuozzo.com>,
	Davidlohr Bueso <dave@stgolabs.net>,
	Nikolay Aleksandrov <nikolay@cumulusnetworks.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	Alexander Potapenko <glider@google.com>,
	linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org
Subject: [PATCH v2 2/7] kfence: Wrap hrtimer to provide a time source for a kfence
Date: Sun, 17 Jul 2016 13:58:02 +0100	[thread overview]
Message-ID: <1468760287-731-3-git-send-email-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <1468760287-731-1-git-send-email-chris@chris-wilson.co.uk>

A common requirement when scheduling a task is that it should be not be
begun until a certain point in time is passed (e.g.
queue_delayed_work()).  kfence_await_hrtimer() causes the kfence to
asynchronously wait until after the appropriate time before being woken.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-media@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org
---
 include/linux/kfence.h |  5 +++++
 kernel/kfence.c        | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/test-kfence.c      | 44 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 6e32385b3b8c..76a2f95dfb70 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -16,6 +16,7 @@
 #include <linux/wait.h>
 
 struct completion;
+enum hrtimer_mode;
 
 struct kfence {
 	wait_queue_head_t wait;
@@ -43,6 +44,10 @@ int kfence_await_kfence(struct kfence *fence,
 int kfence_await_completion(struct kfence *fence,
 			    struct completion *x,
 			    gfp_t gfp);
+int kfence_await_hrtimer(struct kfence *fence,
+			 clockid_t clock, enum hrtimer_mode mode,
+			 ktime_t delay, u64 slack,
+			 gfp_t gfp);
 void kfence_complete(struct kfence *fence);
 void kfence_wake_up_all(struct kfence *fence);
 void kfence_wait(struct kfence *fence);
diff --git a/kernel/kfence.c b/kernel/kfence.c
index 693af9da545a..59c27910a749 100644
--- a/kernel/kfence.c
+++ b/kernel/kfence.c
@@ -48,6 +48,9 @@
  * - kfence_await_completion(): the kfence asynchronously waits upon a
  *   completion
  *
+ * - kfence_await_hrtimer(): the kfence asynchronously wait for an expiration
+ *   of a timer
+ *
  * A kfence is initialised using kfence_init(), and starts off awaiting an
  * event. Once you have finished setting up the fence, including adding
  * all of its asynchronous waits, call kfence_complete().
@@ -429,3 +432,58 @@ int kfence_await_completion(struct kfence *fence,
 	return pending;
 }
 EXPORT_SYMBOL_GPL(kfence_await_completion);
+
+struct timer_cb {
+	struct hrtimer timer;
+	struct kfence *fence;
+};
+
+static enum hrtimer_restart
+timer_kfence_wake(struct hrtimer *timer)
+{
+	struct timer_cb *cb = container_of(timer, typeof(*cb), timer);
+
+	kfence_complete(cb->fence);
+	kfence_put(cb->fence);
+	kfree(cb);
+
+	return HRTIMER_NORESTART;
+}
+
+/**
+ * kfence_await_hrtimer - set the fence to wait for a period of time
+ * @fence: this kfence
+ * @clock: which clock to program
+ * @mode: delay given as relative or absolute
+ * @delay: how long or until what time to wait
+ * @slack: how much slack that may be applied to the delay
+ *
+ * kfence_await_hrtimer() causes the @fence to wait for a a period of time, or
+ * until a certain point in time. It is a convenience wrapper around
+ * hrtimer_start_range_ns(). For more details on @clock, @mode, @delay and
+ * @slack please consult the hrtimer documentation.
+ *
+ * Returns 1 if the delay was sucessfuly added to the @fence, or a negative
+ * error code on failure.
+ */
+int kfence_await_hrtimer(struct kfence *fence,
+			 clockid_t clock, enum hrtimer_mode mode,
+			 ktime_t delay, u64 slack,
+			 gfp_t gfp)
+{
+	struct timer_cb *cb;
+
+	cb = kmalloc(sizeof(*cb), gfp);
+	if (!cb)
+		return -ENOMEM;
+
+	cb->fence = kfence_get(fence);
+	kfence_await(fence);
+
+	hrtimer_init(&cb->timer, clock, mode);
+	cb->timer.function = timer_kfence_wake;
+
+	hrtimer_start_range_ns(&cb->timer, delay, slack, mode);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(kfence_await_hrtimer);
diff --git a/lib/test-kfence.c b/lib/test-kfence.c
index b40719fce967..1b0853fda7c3 100644
--- a/lib/test-kfence.c
+++ b/lib/test-kfence.c
@@ -352,6 +352,44 @@ static int __init test_completion(void)
 	return 0;
 }
 
+static int __init test_delay(void)
+{
+	struct kfence *fence;
+	ktime_t delay;
+	int ret;
+
+	/* Test use of a hrtimer as an event source for kfences */
+	pr_debug("%s\n", __func__);
+
+	fence = alloc_kfence();
+	if (!fence)
+		return -ENOMEM;
+
+	delay = ktime_get();
+
+	ret = kfence_await_hrtimer(fence, CLOCK_MONOTONIC, HRTIMER_MODE_REL,
+				   ms_to_ktime(1), 1 << 10,
+				   GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+	if (ret == 0)
+		return -EINVAL;
+
+	kfence_complete(fence);
+	kfence_wait(fence);
+
+	delay = ktime_sub(ktime_get(), delay);
+	kfence_put(fence);
+
+	if (!ktime_to_ms(delay)) {
+		pr_err("kfence woke too early, delay was only %lldns\n",
+		       (long long)ktime_to_ns(delay));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 struct task_ipc {
 	struct work_struct work;
 	struct completion started;
@@ -522,6 +560,12 @@ static int __init test_kfence_init(void)
 		return ret;
 	}
 
+	ret = test_delay();
+	if (ret < 0) {
+		pr_err("delay failed\n");
+		return ret;
+	}
+
 	return 0;
 }
 
-- 
2.8.1

WARNING: multiple messages have this Message-ID (diff)
From: Chris Wilson <chris@chris-wilson.co.uk>
To: linux-kernel@vger.kernel.org
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>,
	dri-devel@lists.freedesktop.org,
	Alexander Potapenko <glider@google.com>,
	Ingo Molnar <mingo@kernel.org>,
	Davidlohr Bueso <dave@stgolabs.net>,
	Shuah Khan <shuahkh@osg.samsung.com>,
	Andrey Ryabinin <aryabinin@virtuozzo.com>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	linux-media@vger.kernel.org, Kees Cook <keescook@chromium.org>,
	Nikolay Aleksandrov <nikolay@cumulusnetworks.com>,
	linaro-mm-sig@lists.linaro.org,
	Dan Williams <dan.j.williams@intel.com>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	Thomas Gleixner <tglx@linutronix.de>, Tejun Heo <tj@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH v2 2/7] kfence: Wrap hrtimer to provide a time source for a kfence
Date: Sun, 17 Jul 2016 13:58:02 +0100	[thread overview]
Message-ID: <1468760287-731-3-git-send-email-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <1468760287-731-1-git-send-email-chris@chris-wilson.co.uk>

A common requirement when scheduling a task is that it should be not be
begun until a certain point in time is passed (e.g.
queue_delayed_work()).  kfence_await_hrtimer() causes the kfence to
asynchronously wait until after the appropriate time before being woken.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-media@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org
---
 include/linux/kfence.h |  5 +++++
 kernel/kfence.c        | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/test-kfence.c      | 44 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 6e32385b3b8c..76a2f95dfb70 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -16,6 +16,7 @@
 #include <linux/wait.h>
 
 struct completion;
+enum hrtimer_mode;
 
 struct kfence {
 	wait_queue_head_t wait;
@@ -43,6 +44,10 @@ int kfence_await_kfence(struct kfence *fence,
 int kfence_await_completion(struct kfence *fence,
 			    struct completion *x,
 			    gfp_t gfp);
+int kfence_await_hrtimer(struct kfence *fence,
+			 clockid_t clock, enum hrtimer_mode mode,
+			 ktime_t delay, u64 slack,
+			 gfp_t gfp);
 void kfence_complete(struct kfence *fence);
 void kfence_wake_up_all(struct kfence *fence);
 void kfence_wait(struct kfence *fence);
diff --git a/kernel/kfence.c b/kernel/kfence.c
index 693af9da545a..59c27910a749 100644
--- a/kernel/kfence.c
+++ b/kernel/kfence.c
@@ -48,6 +48,9 @@
  * - kfence_await_completion(): the kfence asynchronously waits upon a
  *   completion
  *
+ * - kfence_await_hrtimer(): the kfence asynchronously wait for an expiration
+ *   of a timer
+ *
  * A kfence is initialised using kfence_init(), and starts off awaiting an
  * event. Once you have finished setting up the fence, including adding
  * all of its asynchronous waits, call kfence_complete().
@@ -429,3 +432,58 @@ int kfence_await_completion(struct kfence *fence,
 	return pending;
 }
 EXPORT_SYMBOL_GPL(kfence_await_completion);
+
+struct timer_cb {
+	struct hrtimer timer;
+	struct kfence *fence;
+};
+
+static enum hrtimer_restart
+timer_kfence_wake(struct hrtimer *timer)
+{
+	struct timer_cb *cb = container_of(timer, typeof(*cb), timer);
+
+	kfence_complete(cb->fence);
+	kfence_put(cb->fence);
+	kfree(cb);
+
+	return HRTIMER_NORESTART;
+}
+
+/**
+ * kfence_await_hrtimer - set the fence to wait for a period of time
+ * @fence: this kfence
+ * @clock: which clock to program
+ * @mode: delay given as relative or absolute
+ * @delay: how long or until what time to wait
+ * @slack: how much slack that may be applied to the delay
+ *
+ * kfence_await_hrtimer() causes the @fence to wait for a a period of time, or
+ * until a certain point in time. It is a convenience wrapper around
+ * hrtimer_start_range_ns(). For more details on @clock, @mode, @delay and
+ * @slack please consult the hrtimer documentation.
+ *
+ * Returns 1 if the delay was sucessfuly added to the @fence, or a negative
+ * error code on failure.
+ */
+int kfence_await_hrtimer(struct kfence *fence,
+			 clockid_t clock, enum hrtimer_mode mode,
+			 ktime_t delay, u64 slack,
+			 gfp_t gfp)
+{
+	struct timer_cb *cb;
+
+	cb = kmalloc(sizeof(*cb), gfp);
+	if (!cb)
+		return -ENOMEM;
+
+	cb->fence = kfence_get(fence);
+	kfence_await(fence);
+
+	hrtimer_init(&cb->timer, clock, mode);
+	cb->timer.function = timer_kfence_wake;
+
+	hrtimer_start_range_ns(&cb->timer, delay, slack, mode);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(kfence_await_hrtimer);
diff --git a/lib/test-kfence.c b/lib/test-kfence.c
index b40719fce967..1b0853fda7c3 100644
--- a/lib/test-kfence.c
+++ b/lib/test-kfence.c
@@ -352,6 +352,44 @@ static int __init test_completion(void)
 	return 0;
 }
 
+static int __init test_delay(void)
+{
+	struct kfence *fence;
+	ktime_t delay;
+	int ret;
+
+	/* Test use of a hrtimer as an event source for kfences */
+	pr_debug("%s\n", __func__);
+
+	fence = alloc_kfence();
+	if (!fence)
+		return -ENOMEM;
+
+	delay = ktime_get();
+
+	ret = kfence_await_hrtimer(fence, CLOCK_MONOTONIC, HRTIMER_MODE_REL,
+				   ms_to_ktime(1), 1 << 10,
+				   GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+	if (ret == 0)
+		return -EINVAL;
+
+	kfence_complete(fence);
+	kfence_wait(fence);
+
+	delay = ktime_sub(ktime_get(), delay);
+	kfence_put(fence);
+
+	if (!ktime_to_ms(delay)) {
+		pr_err("kfence woke too early, delay was only %lldns\n",
+		       (long long)ktime_to_ns(delay));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 struct task_ipc {
 	struct work_struct work;
 	struct completion started;
@@ -522,6 +560,12 @@ static int __init test_kfence_init(void)
 		return ret;
 	}
 
+	ret = test_delay();
+	if (ret < 0) {
+		pr_err("delay failed\n");
+		return ret;
+	}
+
 	return 0;
 }
 
-- 
2.8.1

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

  parent reply	other threads:[~2016-07-17 12:59 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-24  9:08 Introduce fences for N:M completion variables Chris Wilson
2016-06-24  9:08 ` [PATCH 1/9] lib: Add kselftests for async-domains Chris Wilson
2016-06-24  9:08 ` [PATCH 2/9] async: Introduce kfence, a N:M completion mechanism Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-07-13  9:38   ` Peter Zijlstra
2016-07-13  9:38     ` Peter Zijlstra
2016-07-13 10:20     ` Chris Wilson
2016-07-13 10:20       ` Chris Wilson
2016-07-13 11:02       ` Daniel Vetter
2016-07-13 11:02         ` Daniel Vetter
2016-07-13 10:26   ` Peter Zijlstra
2016-07-13 10:26     ` Peter Zijlstra
2016-06-24  9:08 ` [PATCH 3/9] async: Extend kfence to allow struct embedding Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-07-13 10:31   ` Peter Zijlstra
2016-06-24  9:08 ` [PATCH 4/9] async: Extend kfences for listening on DMA fences Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-06-24  9:08 ` [PATCH 5/9] async: Wrap hrtimer to provide a time source for a kfence Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-07-13 10:32   ` Peter Zijlstra
2016-06-24  9:08 ` [PATCH 6/9] async: Add a convenience wrapper for waiting on implicit dma-buf Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-06-24  9:08 ` [PATCH 7/9] async: Add support for explicit fine-grained barriers Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-06-24  9:08 ` [PATCH 8/9] async: Add execution barriers Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-06-24  9:08 ` [PATCH 9/9] async: Introduce a dependency resolver for parallel execution Chris Wilson
2016-06-24  9:08   ` Chris Wilson
2016-07-17 12:58 ` Introduce fences for N:M completion variables [v2] Chris Wilson
2016-07-17 12:58   ` Chris Wilson
2016-07-17 12:58   ` [PATCH v2 1/7] kfence: Introduce kfence, a N:M completion mechanism Chris Wilson
2016-07-17 12:58     ` Chris Wilson
2016-07-17 12:58   ` Chris Wilson [this message]
2016-07-17 12:58     ` [PATCH v2 2/7] kfence: Wrap hrtimer to provide a time source for a kfence Chris Wilson
2016-07-17 12:58   ` [PATCH v2 3/7] kfence: Extend kfences for listening on DMA fences Chris Wilson
2016-07-17 12:58     ` Chris Wilson
2016-07-17 12:58   ` [PATCH v2 4/7] async: Add kselftests for async-domains Chris Wilson
2016-07-17 12:58     ` Chris Wilson
2016-07-17 12:58   ` [PATCH v2 5/7] async: Add support for explicit fine-grained barriers Chris Wilson
2016-07-17 12:58     ` Chris Wilson
2016-07-17 12:58   ` [PATCH v2 6/7] async: Add execution barriers Chris Wilson
2016-07-17 12:58     ` Chris Wilson
2016-07-17 12:58   ` [PATCH v2 7/7] async: Introduce a dependency resolver for parallel execution Chris Wilson
2016-07-17 12:58     ` Chris Wilson

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=1468760287-731-3-git-send-email-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=aryabinin@virtuozzo.com \
    --cc=dan.j.williams@intel.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dave@stgolabs.net \
    --cc=davem@davemloft.net \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=keescook@chromium.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux@rasmusvillemoes.dk \
    --cc=mingo@kernel.org \
    --cc=nikolay@cumulusnetworks.com \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=peterz@infradead.org \
    --cc=shuahkh@osg.samsung.com \
    --cc=sumit.semwal@linaro.org \
    --cc=tglx@linutronix.de \
    --cc=tj@kernel.org \
    /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.