Commit a8a4021b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull core fixes from Thomas Gleixner:
 "A small set of core updates:

   - Make objtool cope with GCC8 oddities some more

   - Remove a stale local_irq_save/restore sequence in the signal code
     along with the stale comment in the RCU code. The underlying issue
     which led to this has been solved long time ago, but nobody cared
     to cleanup the hackarounds"

* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  signal: Remove no longer required irqsave/restore
  rcu: Update documentation of rcu_read_unlock()
  objtool: Fix GCC 8 cold subfunction detection for aliased functions
parents 3ca24ce9 59dc6f3c
...@@ -652,9 +652,7 @@ static inline void rcu_read_lock(void) ...@@ -652,9 +652,7 @@ static inline void rcu_read_lock(void)
* Unfortunately, this function acquires the scheduler's runqueue and * Unfortunately, this function acquires the scheduler's runqueue and
* priority-inheritance spinlocks. This means that deadlock could result * priority-inheritance spinlocks. This means that deadlock could result
* if the caller of rcu_read_unlock() already holds one of these locks or * if the caller of rcu_read_unlock() already holds one of these locks or
* any lock that is ever acquired while holding them; or any lock which * any lock that is ever acquired while holding them.
* can be taken from interrupt context because rcu_boost()->rt_mutex_lock()
* does not disable irqs while taking ->wait_lock.
* *
* That said, RCU readers are never priority boosted unless they were * That said, RCU readers are never priority boosted unless they were
* preempted. Therefore, one way to avoid deadlock is to make sure * preempted. Therefore, one way to avoid deadlock is to make sure
......
...@@ -1244,19 +1244,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, ...@@ -1244,19 +1244,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
{ {
struct sighand_struct *sighand; struct sighand_struct *sighand;
rcu_read_lock();
for (;;) { for (;;) {
/*
* Disable interrupts early to avoid deadlocks.
* See rcu_read_unlock() comment header for details.
*/
local_irq_save(*flags);
rcu_read_lock();
sighand = rcu_dereference(tsk->sighand); sighand = rcu_dereference(tsk->sighand);
if (unlikely(sighand == NULL)) { if (unlikely(sighand == NULL))
rcu_read_unlock();
local_irq_restore(*flags);
break; break;
}
/* /*
* This sighand can be already freed and even reused, but * This sighand can be already freed and even reused, but
* we rely on SLAB_TYPESAFE_BY_RCU and sighand_ctor() which * we rely on SLAB_TYPESAFE_BY_RCU and sighand_ctor() which
...@@ -1268,15 +1261,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, ...@@ -1268,15 +1261,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
* __exit_signal(). In the latter case the next iteration * __exit_signal(). In the latter case the next iteration
* must see ->sighand == NULL. * must see ->sighand == NULL.
*/ */
spin_lock(&sighand->siglock); spin_lock_irqsave(&sighand->siglock, *flags);
if (likely(sighand == tsk->sighand)) { if (likely(sighand == tsk->sighand))
rcu_read_unlock();
break; break;
} spin_unlock_irqrestore(&sighand->siglock, *flags);
spin_unlock(&sighand->siglock);
rcu_read_unlock();
local_irq_restore(*flags);
} }
rcu_read_unlock();
return sighand; return sighand;
} }
......
...@@ -543,6 +543,28 @@ static int add_jump_destinations(struct objtool_file *file) ...@@ -543,6 +543,28 @@ static int add_jump_destinations(struct objtool_file *file)
dest_off); dest_off);
return -1; return -1;
} }
/*
* For GCC 8+, create parent/child links for any cold
* subfunctions. This is _mostly_ redundant with a similar
* initialization in read_symbols().
*
* If a function has aliases, we want the *first* such function
* in the symbol table to be the subfunction's parent. In that
* case we overwrite the initialization done in read_symbols().
*
* However this code can't completely replace the
* read_symbols() code because this doesn't detect the case
* where the parent function's only reference to a subfunction
* is through a switch table.
*/
if (insn->func && insn->jump_dest->func &&
insn->func != insn->jump_dest->func &&
!strstr(insn->func->name, ".cold.") &&
strstr(insn->jump_dest->func->name, ".cold.")) {
insn->func->cfunc = insn->jump_dest->func;
insn->jump_dest->func->pfunc = insn->func;
}
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment