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
next prev 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: linkBe 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.