Dear RT Folks,

I'm pleased to announce the 3.4.72-rt90 stable release.


You can get this release via the git tree at:

  git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git

  branch: v3.4-rt
  Head SHA1: 691eae354832e65db69742765fc5c20e9ffbb5ee


Or to build 3.4.72-rt90 directly, the following patches should be applied:

  http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.4.tar.xz

  http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.4.72.xz

  
http://www.kernel.org/pub/linux/kernel/projects/rt/3.4/patch-3.4.72-rt90.patch.xz



You can also build from 3.4.72-rt89 by applying the incremental patch:

  
http://www.kernel.org/pub/linux/kernel/projects/rt/3.4/incr/patch-3.4.72-rt89-rt90.patch.xz



Enjoy,

-- Steve


Changes from v3.4.72-rt89:

---

Peter Zijlstra (1):
      lockdep: Correctly annotate hardirq context in irq_exit()

Sebastian Andrzej Siewior (2):
      swait: Add a few more users
      rtmutex: use a trylock for waiter lock in trylock

Sebastian Siewior (1):
      net: make neigh_priv_len in struct net_device 16bit instead of 8bit

Steven Rostedt (Red Hat) (1):
      Linux 3.4.72-rt90

Tiejun Chen (1):
      cpu_down: move migrate_enable() back

----
 drivers/net/wireless/orinoco/orinoco_usb.c |  2 +-
 drivers/usb/gadget/f_fs.c                  |  2 +-
 drivers/usb/gadget/inode.c                 |  4 +--
 include/linux/netdevice.h                  |  2 +-
 include/linux/spinlock_rt.h                |  1 +
 kernel/cpu.c                               |  2 +-
 kernel/rtmutex.c                           | 31 +++++++++++++++++---
 kernel/softirq.c                           | 45 ++++++++++++++++++++++++++++--
 kernel/timer.c                             |  2 +-
 localversion-rt                            |  2 +-
 10 files changed, 78 insertions(+), 15 deletions(-)
---------------------------
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c 
b/drivers/net/wireless/orinoco/orinoco_usb.c
index f634d45..8152c94 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -714,7 +714,7 @@ static void ezusb_req_ctx_wait(struct ezusb_priv *upriv,
                        while (!ctx->done.done && msecs--)
                                udelay(1000);
                } else {
-                       wait_event_interruptible(ctx->done.wait,
+                       swait_event_interruptible(ctx->done.wait,
                                                 ctx->done.done);
                }
                break;
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index f52cb1a..54ea4e9 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1255,7 +1255,7 @@ static void ffs_data_put(struct ffs_data *ffs)
                pr_info("%s(): freeing\n", __func__);
                ffs_data_clear(ffs);
                BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
-                      waitqueue_active(&ffs->ep0req_completion.wait));
+                      swaitqueue_active(&ffs->ep0req_completion.wait));
                kfree(ffs);
        }
 }
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index e58b164..2dfd196 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -339,7 +339,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)
        spin_unlock_irq (&epdata->dev->lock);
 
        if (likely (value == 0)) {
-               value = wait_event_interruptible (done.wait, done.done);
+               value = swait_event_interruptible (done.wait, done.done);
                if (value != 0) {
                        spin_lock_irq (&epdata->dev->lock);
                        if (likely (epdata->ep != NULL)) {
@@ -348,7 +348,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)
                                usb_ep_dequeue (epdata->ep, epdata->req);
                                spin_unlock_irq (&epdata->dev->lock);
 
-                               wait_event (done.wait, done.done);
+                               swait_event (done.wait, done.done);
                                if (epdata->status == -ECONNRESET)
                                        epdata->status = -EINTR;
                        } else {
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 40940f5..65d8385 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1109,7 +1109,7 @@ struct net_device {
        unsigned char           perm_addr[MAX_ADDR_LEN]; /* permanent hw 
address */
        unsigned char           addr_assign_type; /* hw address assignment type 
*/
        unsigned char           addr_len;       /* hardware address length      
*/
-       unsigned char           neigh_priv_len;
+       unsigned short          neigh_priv_len;
        unsigned short          dev_id;         /* for shared network cards */
 
        spinlock_t              addr_list_lock;
diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h
index 0618387..b3c504b 100644
--- a/include/linux/spinlock_rt.h
+++ b/include/linux/spinlock_rt.h
@@ -22,6 +22,7 @@ extern void __lockfunc rt_spin_lock(spinlock_t *lock);
 extern unsigned long __lockfunc rt_spin_lock_trace_flags(spinlock_t *lock);
 extern void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass);
 extern void __lockfunc rt_spin_unlock(spinlock_t *lock);
+extern void __lockfunc rt_spin_unlock_after_trylock_in_irq(spinlock_t *lock);
 extern void __lockfunc rt_spin_unlock_wait(spinlock_t *lock);
 extern int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long 
*flags);
 extern int __lockfunc rt_spin_trylock_bh(spinlock_t *lock);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index c18c25e..4e3b7c5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -545,6 +545,7 @@ static int __ref _cpu_down(unsigned int cpu, int 
tasks_frozen)
                err = -EBUSY;
                goto restore_cpus;
        }
+       migrate_enable();
 
        cpu_hotplug_begin();
        err = cpu_unplug_begin(cpu);
@@ -597,7 +598,6 @@ static int __ref _cpu_down(unsigned int cpu, int 
tasks_frozen)
 out_release:
        cpu_unplug_done(cpu);
 out_cancel:
-       migrate_enable();
        cpu_hotplug_done();
        if (!err)
                cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 20742e7..3825e1c 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -801,10 +801,8 @@ static void  noinline __sched rt_spin_lock_slowlock(struct 
rt_mutex *lock)
 /*
  * Slow path to release a rt_mutex spin_lock style
  */
-static void  noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock)
+static void __sched __rt_spin_lock_slowunlock(struct rt_mutex *lock)
 {
-       raw_spin_lock(&lock->wait_lock);
-
        debug_rt_mutex_unlock(lock);
 
        rt_mutex_deadlock_account_unlock(current);
@@ -823,6 +821,23 @@ static void  noinline __sched 
rt_spin_lock_slowunlock(struct rt_mutex *lock)
        rt_mutex_adjust_prio(current);
 }
 
+static void  noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock)
+{
+       raw_spin_lock(&lock->wait_lock);
+       __rt_spin_lock_slowunlock(lock);
+}
+
+static void  noinline __sched rt_spin_lock_slowunlock_hirq(struct rt_mutex 
*lock)
+{
+       int ret;
+
+       do {
+               ret = raw_spin_trylock(&lock->wait_lock);
+       } while (!ret);
+
+       __rt_spin_lock_slowunlock(lock);
+}
+
 void __lockfunc rt_spin_lock(spinlock_t *lock)
 {
        rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock);
@@ -853,6 +868,13 @@ void __lockfunc rt_spin_unlock(spinlock_t *lock)
 }
 EXPORT_SYMBOL(rt_spin_unlock);
 
+void __lockfunc rt_spin_unlock_after_trylock_in_irq(spinlock_t *lock)
+{
+       /* NOTE: we always pass in '1' for nested, for simplicity */
+       spin_release(&lock->dep_map, 1, _RET_IP_);
+       rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock_hirq);
+}
+
 void __lockfunc __rt_spin_unlock(struct rt_mutex *lock)
 {
        rt_spin_lock_fastunlock(lock, rt_spin_lock_slowunlock);
@@ -1056,7 +1078,8 @@ rt_mutex_slowtrylock(struct rt_mutex *lock)
 {
        int ret = 0;
 
-       raw_spin_lock(&lock->wait_lock);
+       if (!raw_spin_trylock(&lock->wait_lock))
+               return ret;
        init_lists(lock);
 
        if (likely(rt_mutex_owner(lock) != current)) {
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 34fe1db..c2c6bc8 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -297,6 +297,44 @@ EXPORT_SYMBOL(local_bh_enable_ip);
  */
 #define MAX_SOFTIRQ_RESTART 10
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+/*
+ * Convoluted means of passing __do_softirq() a message through the various
+ * architecture execute_on_stack() bits.
+ *
+ * When we run softirqs from irq_exit() and thus on the hardirq stack we need
+ * to keep the lockdep irq context tracking as tight as possible in order to
+ * not miss-qualify lock contexts and miss possible deadlocks.
+ */
+static DEFINE_PER_CPU(int, softirq_from_hardirq);
+
+static inline void lockdep_softirq_from_hardirq(void)
+{
+       this_cpu_write(softirq_from_hardirq, 1);
+}
+
+static inline void lockdep_softirq_start(void)
+{
+       if (this_cpu_read(softirq_from_hardirq))
+               trace_hardirq_exit();
+       lockdep_softirq_enter();
+}
+
+static inline void lockdep_softirq_end(void)
+{
+       lockdep_softirq_exit();
+       if (this_cpu_read(softirq_from_hardirq)) {
+               this_cpu_write(softirq_from_hardirq, 0);
+               trace_hardirq_enter();
+       }
+}
+
+#else
+static inline void lockdep_softirq_from_hardirq(void) { }
+static inline void lockdep_softirq_start(void) { }
+static inline void lockdep_softirq_end(void) { }
+#endif
+
 asmlinkage void __do_softirq(void)
 {
        __u32 pending;
@@ -308,7 +346,7 @@ asmlinkage void __do_softirq(void)
 
        __local_bh_disable((unsigned long)__builtin_return_address(0),
                           SOFTIRQ_OFFSET);
-       lockdep_softirq_enter();
+       lockdep_softirq_start();
 
        cpu = smp_processor_id();
 restart:
@@ -324,7 +362,7 @@ restart:
        if (pending)
                wakeup_softirqd();
 
-       lockdep_softirq_exit();
+       lockdep_softirq_end();
 
        account_system_vtime(current);
        __local_bh_enable(SOFTIRQ_OFFSET);
@@ -582,6 +620,7 @@ static inline void invoke_softirq(void)
 {
 #ifndef CONFIG_PREEMPT_RT_FULL
        if (!force_irqthreads) {
+               lockdep_softirq_from_hardirq();
 #ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
                __do_softirq();
 #else
@@ -604,7 +643,6 @@ static inline void invoke_softirq(void)
 void irq_exit(void)
 {
        account_system_vtime(current);
-       trace_hardirq_exit();
        sub_preempt_count(IRQ_EXIT_OFFSET);
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
@@ -615,6 +653,7 @@ void irq_exit(void)
                tick_nohz_irq_exit();
 #endif
        rcu_irq_exit();
+       trace_hardirq_exit(); /* must be last! */
        sched_preempt_enable_no_resched();
 }
 
diff --git a/kernel/timer.c b/kernel/timer.c
index 78f07e5..fb1c00d 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1386,7 +1386,7 @@ unsigned long get_next_timer_interrupt(unsigned long now)
                if (time_before_eq(base->next_timer, base->timer_jiffies))
                        base->next_timer = __next_timer_interrupt(base);
                expires = base->next_timer;
-               rt_spin_unlock(&base->lock);
+               rt_spin_unlock_after_trylock_in_irq(&base->lock);
        } else {
                expires = now + 1;
        }
diff --git a/localversion-rt b/localversion-rt
index d2a4022..cda29c6 100644
--- a/localversion-rt
+++ b/localversion-rt
@@ -1 +1 @@
--rt89
+-rt90
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to