Skip to content

Commit a8a4021

Browse files
committed
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
2 parents 3ca24ce + 59dc6f3 commit a8a4021

File tree

3 files changed

+30
-20
lines changed

3 files changed

+30
-20
lines changed

include/linux/rcupdate.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,9 +652,7 @@ static inline void rcu_read_lock(void)
652652
* Unfortunately, this function acquires the scheduler's runqueue and
653653
* priority-inheritance spinlocks. This means that deadlock could result
654654
* if the caller of rcu_read_unlock() already holds one of these locks or
655-
* any lock that is ever acquired while holding them; or any lock which
656-
* can be taken from interrupt context because rcu_boost()->rt_mutex_lock()
657-
* does not disable irqs while taking ->wait_lock.
655+
* any lock that is ever acquired while holding them.
658656
*
659657
* That said, RCU readers are never priority boosted unless they were
660658
* preempted. Therefore, one way to avoid deadlock is to make sure

kernel/signal.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,19 +1244,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
12441244
{
12451245
struct sighand_struct *sighand;
12461246

1247+
rcu_read_lock();
12471248
for (;;) {
1248-
/*
1249-
* Disable interrupts early to avoid deadlocks.
1250-
* See rcu_read_unlock() comment header for details.
1251-
*/
1252-
local_irq_save(*flags);
1253-
rcu_read_lock();
12541249
sighand = rcu_dereference(tsk->sighand);
1255-
if (unlikely(sighand == NULL)) {
1256-
rcu_read_unlock();
1257-
local_irq_restore(*flags);
1250+
if (unlikely(sighand == NULL))
12581251
break;
1259-
}
1252+
12601253
/*
12611254
* This sighand can be already freed and even reused, but
12621255
* 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,
12681261
* __exit_signal(). In the latter case the next iteration
12691262
* must see ->sighand == NULL.
12701263
*/
1271-
spin_lock(&sighand->siglock);
1272-
if (likely(sighand == tsk->sighand)) {
1273-
rcu_read_unlock();
1264+
spin_lock_irqsave(&sighand->siglock, *flags);
1265+
if (likely(sighand == tsk->sighand))
12741266
break;
1275-
}
1276-
spin_unlock(&sighand->siglock);
1277-
rcu_read_unlock();
1278-
local_irq_restore(*flags);
1267+
spin_unlock_irqrestore(&sighand->siglock, *flags);
12791268
}
1269+
rcu_read_unlock();
12801270

12811271
return sighand;
12821272
}

tools/objtool/check.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,28 @@ static int add_jump_destinations(struct objtool_file *file)
543543
dest_off);
544544
return -1;
545545
}
546+
547+
/*
548+
* For GCC 8+, create parent/child links for any cold
549+
* subfunctions. This is _mostly_ redundant with a similar
550+
* initialization in read_symbols().
551+
*
552+
* If a function has aliases, we want the *first* such function
553+
* in the symbol table to be the subfunction's parent. In that
554+
* case we overwrite the initialization done in read_symbols().
555+
*
556+
* However this code can't completely replace the
557+
* read_symbols() code because this doesn't detect the case
558+
* where the parent function's only reference to a subfunction
559+
* is through a switch table.
560+
*/
561+
if (insn->func && insn->jump_dest->func &&
562+
insn->func != insn->jump_dest->func &&
563+
!strstr(insn->func->name, ".cold.") &&
564+
strstr(insn->jump_dest->func->name, ".cold.")) {
565+
insn->func->cfunc = insn->jump_dest->func;
566+
insn->jump_dest->func->pfunc = insn->func;
567+
}
546568
}
547569

548570
return 0;

0 commit comments

Comments
 (0)