* [ANNOUNCE] 3.8.13-rt11
@ 2013-06-14 19:30 Sebastian Andrzej Siewior
[not found] ` <51BB7A3D.8070305@osadl.org>
0 siblings, 1 reply; 2+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-06-14 19:30 UTC (permalink / raw)
To: linux-rt-users; +Cc: LKML, Thomas Gleixner, rostedt, John Kacur
Dear RT Folks,
I'm pleased to announce the 3.8.13-rt11 release.
changes since v3.8.13-rt10:
- use wakeup_timer_waiters() in wake_up() so we do nothing on nort
kernel. Sent by Zhao Hongjiang
- a fix for a cpu down problem. If kthread is pinned to the same CPU
which is going down we will spin for ever and wait until kthread
leaves the CPU. This does not trigger on v3.6-rt because the workqueue
code there does not create a new process in the notfier callback.
Reported by Qiang Huang.
- a check if we lose PF_THREAD_BOUND in the workqueue code. Shouldn't
happen yet it seems it happens from time to time.
- save the cpu mask of the application which disables a CPU. Prior this
change the application which put a CPU down was allowed to run on any
CPU if it was restricted to a specifc one. Reported by Zhao Chenhui.
- the SLxB PowerPC, e500 problem is removed from the list without a
change. The problem triggers even on a v3.6 non-RT kernel after 1-2
days of runtime on my MPC8572DS. I don't see any problem so far on
MPC8536 which is mostly the same HW except it is UP but MPC8572DS
crashes also in UP mode so I belive it is a HW problem.
Known issues:
- Steven reported a missing acpi from the v3.6 release.
- a "fix" for i915 leads to high latencies due to wbinvd(). Not sure
what is the best thing to do here.
The delta patch against v3.8.13-rt10 is appended below and can be found here:
https://www.kernel.org/pub/linux/kernel/projects/rt/3.8/incr/patch-3.8.13-rt10-rt11.patch.xz
The RT patch against 3.8.11 can be found here:
https://www.kernel.org/pub/linux/kernel/projects/rt/3.8/patch-3.8.13-rt11.patch.xz
The split quilt queue is available at:
https://www.kernel.org/pub/linux/kernel/projects/rt/3.8/patches-3.8.13-rt11.tar.xz
Sebastian
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d44dea3..f5ad8e1 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -83,6 +83,7 @@ struct hotplug_pcp {
int refcount;
int grab_lock;
struct completion synced;
+ struct completion unplug_wait;
#ifdef CONFIG_PREEMPT_RT_FULL
spinlock_t lock;
#else
@@ -180,6 +181,7 @@ static int sync_unplug_thread(void *data)
{
struct hotplug_pcp *hp = data;
+ wait_for_completion(&hp->unplug_wait);
preempt_disable();
hp->unplug = current;
wait_for_pinned_cpus(hp);
@@ -245,6 +247,14 @@ static void __cpu_unplug_sync(struct hotplug_pcp *hp)
wait_for_completion(&hp->synced);
}
+static void __cpu_unplug_wait(unsigned int cpu)
+{
+ struct hotplug_pcp *hp = &per_cpu(hotplug_pcp, cpu);
+
+ complete(&hp->unplug_wait);
+ wait_for_completion(&hp->synced);
+}
+
/*
* Start the sync_unplug_thread on the target cpu and wait for it to
* complete.
@@ -268,6 +278,7 @@ static int cpu_unplug_begin(unsigned int cpu)
tell_sched_cpu_down_begin(cpu);
init_completion(&hp->synced);
+ init_completion(&hp->unplug_wait);
hp->sync_tsk = kthread_create(sync_unplug_thread, hp, "sync_unplug/%d", cpu);
if (IS_ERR(hp->sync_tsk)) {
@@ -283,8 +294,7 @@ static int cpu_unplug_begin(unsigned int cpu)
* wait for tasks that are going to enter these sections and
* we must not have them block.
*/
- __cpu_unplug_sync(hp);
-
+ wake_up_process(hp->sync_tsk);
return 0;
}
@@ -535,6 +545,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
.hcpu = hcpu,
};
cpumask_var_t cpumask;
+ cpumask_var_t cpumask_org;
if (num_online_cpus() == 1)
return -EBUSY;
@@ -545,6 +556,12 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
/* Move the downtaker off the unplug cpu */
if (!alloc_cpumask_var(&cpumask, GFP_KERNEL))
return -ENOMEM;
+ if (!alloc_cpumask_var(&cpumask_org, GFP_KERNEL)) {
+ free_cpumask_var(cpumask);
+ return -ENOMEM;
+ }
+
+ cpumask_copy(cpumask_org, tsk_cpus_allowed(current));
cpumask_andnot(cpumask, cpu_online_mask, cpumask_of(cpu));
set_cpus_allowed_ptr(current, cpumask);
free_cpumask_var(cpumask);
@@ -553,7 +570,8 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
if (mycpu == cpu) {
printk(KERN_ERR "Yuck! Still on unplug CPU\n!");
migrate_enable();
- return -EBUSY;
+ err = -EBUSY;
+ goto restore_cpus;
}
cpu_hotplug_begin();
@@ -571,6 +589,8 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
__func__, cpu);
goto out_release;
}
+
+ __cpu_unplug_wait(cpu);
smpboot_park_threads(cpu);
/* Notifiers are done. Don't let any more tasks pin this CPU. */
@@ -610,6 +630,9 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
cpu_hotplug_done();
if (!err)
cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
+restore_cpus:
+ set_cpus_allowed_ptr(current, cpumask_org);
+ free_cpumask_var(cpumask_org);
return err;
}
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 1fba5cb..81a28dd 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -849,9 +849,6 @@ static void irq_thread_dtor(struct callback_head *unused)
static int irq_thread(void *data)
{
struct callback_head on_exit_work;
- static const struct sched_param param = {
- .sched_priority = MAX_USER_RT_PRIO/2,
- };
struct irqaction *action = data;
struct irq_desc *desc = irq_to_desc(action->irq);
irqreturn_t (*handler_fn)(struct irq_desc *desc,
@@ -863,8 +860,6 @@ static int irq_thread(void *data)
else
handler_fn = irq_thread_fn;
- sched_setscheduler(current, SCHED_FIFO, ¶m);
-
init_task_work(&on_exit_work, irq_thread_dtor);
task_work_add(current, &on_exit_work, false);
@@ -965,6 +960,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
*/
if (new->thread_fn && !nested) {
struct task_struct *t;
+ static const struct sched_param param = {
+ .sched_priority = MAX_USER_RT_PRIO/2,
+ };
t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
new->name);
@@ -972,6 +970,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
ret = PTR_ERR(t);
goto out_mput;
}
+
+ sched_setscheduler(t, SCHED_FIFO, ¶m);
+
/*
* We keep the reference to the task struct even if
* the thread dies to avoid that the interrupt code
diff --git a/kernel/timer.c b/kernel/timer.c
index 374e7b1..2f1c8d3 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -76,7 +76,9 @@ struct tvec_root {
struct tvec_base {
spinlock_t lock;
struct timer_list *running_timer;
+#ifdef CONFIG_PREEMPT_RT_FULL
wait_queue_head_t wait_for_running_timer;
+#endif
unsigned long timer_jiffies;
unsigned long next_timer;
unsigned long active_timers;
@@ -982,7 +984,7 @@ static void wait_for_running_timer(struct timer_list *timer)
base->running_timer != timer);
}
-# define wakeup_timer_waiters(b) wake_up(&(b)->wait_for_tunning_timer)
+# define wakeup_timer_waiters(b) wake_up(&(b)->wait_for_running_timer)
#else
static inline void wait_for_running_timer(struct timer_list *timer)
{
@@ -1236,7 +1238,7 @@ static inline void __run_timers(struct tvec_base *base)
}
}
}
- wake_up(&base->wait_for_running_timer);
+ wakeup_timer_waiters(base);
spin_unlock_irq(&base->lock);
}
@@ -1755,7 +1757,9 @@ static int __cpuinit init_timers_cpu(int cpu)
}
spin_lock_init(&base->lock);
+#ifdef CONFIG_PREEMPT_RT_FULL
init_waitqueue_head(&base->wait_for_running_timer);
+#endif
for (j = 0; j < TVN_SIZE; j++) {
INIT_LIST_HEAD(base->tv5.vec + j);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 11285e4..0d49ddf 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1637,8 +1637,11 @@ __acquires(&gcwq->lock)
* it races with cpu hotunplug operation. Verify
* against GCWQ_DISASSOCIATED.
*/
- if (!(gcwq->flags & GCWQ_DISASSOCIATED))
+ if (!(gcwq->flags & GCWQ_DISASSOCIATED)) {
set_cpus_allowed_ptr(task, get_cpu_mask(gcwq->cpu));
+ if (WARN_ON(!(task->flags & PF_THREAD_BOUND)))
+ task->flags |= PF_THREAD_BOUND;
+ }
spin_lock_irq(&gcwq->lock);
if (gcwq->flags & GCWQ_DISASSOCIATED)
diff --git a/localversion-rt b/localversion-rt
index d79dde6..05c35cb 100644
--- a/localversion-rt
+++ b/localversion-rt
@@ -1 +1 @@
--rt10
+-rt11
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH] gpu: i915: allow the user not to do the wbinvd ("Was: Re: [ANNOUNCE] 3.8.13-rt11)
[not found] ` <51BB7A3D.8070305@osadl.org>
@ 2013-06-21 9:49 ` Sebastian Andrzej Siewior
0 siblings, 0 replies; 2+ messages in thread
From: Sebastian Andrzej Siewior @ 2013-06-21 9:49 UTC (permalink / raw)
To: Carsten Emde
Cc: Steven Rostedt, Christoph Mathys, Thomas Gleixner, Chris Wilson,
Daniel Vetter, Linux RT Users
* Carsten Emde | 2013-06-14 22:17:01 [+0200]:
>Hi Sebastian,
Hi Carsten,
>> - a "fix" for i915 leads to high latencies due to wbinvd(). Not sure
>> what is the best thing to do here.
>Even if we do not yet know what is the best final solution to this
>problem, there is no doubt that, for the time being, the patch in
>question has to be reverted - the earlier the better. Please
>understand that this RT kernel release it totally unusable on a
>system that is equipped with one of several widely used Intel
>graphics boards. It simply is a waste of time.
Yes but reverting causes problems for others. Anyway, in order to make
progress here and not break anything I include the patch below. So
everyone who does not want the expensive sync can specify
i915.do_wbinvd=no after they ensured that the same CPU is used for GPU
related operations.
Subject: [PATCH] gpu: i915: allow the user not to do the wbinvd
The wbinvd() renders the system with i915 unusable on RT. Using this
expensive instruction avoids GPU trouble according to
https://bugs.freedesktop.org/show_bug.cgi?id=62191
As a workaround for RT it is recommended to pin each GPU related process
to the same CPU and then disable this instruction via the module
paramter.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
drivers/gpu/drm/i915/i915_gem.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 339540d..dce41f4 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -35,6 +35,7 @@
#include <linux/swap.h>
#include <linux/pci.h>
#include <linux/dma-buf.h>
+#include <linux/module.h>
static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
@@ -2656,6 +2657,10 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
return fence - dev_priv->fence_regs;
}
+static bool do_wbinvd = true;
+module_param(do_wbinvd, bool, 0644);
+MODULE_PARM_DESC(do_wbinvd, "Do expensive synchronization. Say no after you pin each GPU process to the same CPU in order to lower the latency.");
+
static void i915_gem_write_fence__ipi(void *data)
{
wbinvd();
@@ -2679,8 +2684,16 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
* on each processor in order to manually flush all memory
* transactions before updating the fence register.
*/
- if (HAS_LLC(obj->base.dev))
- on_each_cpu(i915_gem_write_fence__ipi, NULL, 1);
+ if (HAS_LLC(obj->base.dev)) {
+ if (do_wbinvd) {
+#ifdef CONFIG_PREEMPT_RT_FULL
+ pr_err_once("WARNING! The i915 invalidates all caches which increases the latency.");
+ pr_err_once("As a workaround use 'i915.do_wbinvd=no' and PIN each process doing ");
+ pr_err_once("any kind of GPU activity to the same CPU to avoid problems.");
+#endif
+ on_each_cpu(i915_gem_write_fence__ipi, NULL, 1);
+ }
+ }
i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL);
if (enable) {
--
1.8.3.1
>
> -Carsten.
Sebastian
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-06-21 9:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-14 19:30 [ANNOUNCE] 3.8.13-rt11 Sebastian Andrzej Siewior
[not found] ` <51BB7A3D.8070305@osadl.org>
2013-06-21 9:49 ` [PATCH] gpu: i915: allow the user not to do the wbinvd ("Was: Re: [ANNOUNCE] 3.8.13-rt11) Sebastian Andrzej Siewior
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).