uprobes: Kill UTASK_BP_HIT state
Kill UTASK_BP_HIT state, it buys nothing but complicates the code. It is only used in uprobe_notify_resume() to decide who should be called, we can check utask->active_uprobe != NULL instead. And this allows us to simplify handle_swbp(), no need to clear utask->state. Likewise we could kill UTASK_SSTEP, but UTASK_BP_HIT is worse and imho should die. The problem is, it creates the special case when task->utask is NULL, we can't distinguish RUNNING and BP_HIT. With this patch utask == NULL always means RUNNING. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
This commit is contained in:
Родитель
0578a97098
Коммит
1b08e90721
|
@ -59,7 +59,6 @@ struct uprobe_consumer {
|
||||||
#ifdef CONFIG_UPROBES
|
#ifdef CONFIG_UPROBES
|
||||||
enum uprobe_task_state {
|
enum uprobe_task_state {
|
||||||
UTASK_RUNNING,
|
UTASK_RUNNING,
|
||||||
UTASK_BP_HIT,
|
|
||||||
UTASK_SSTEP,
|
UTASK_SSTEP,
|
||||||
UTASK_SSTEP_ACK,
|
UTASK_SSTEP_ACK,
|
||||||
UTASK_SSTEP_TRAPPED,
|
UTASK_SSTEP_TRAPPED,
|
||||||
|
|
|
@ -1469,10 +1469,6 @@ static void handle_swbp(struct pt_regs *regs)
|
||||||
bp_vaddr = uprobe_get_swbp_addr(regs);
|
bp_vaddr = uprobe_get_swbp_addr(regs);
|
||||||
uprobe = find_active_uprobe(bp_vaddr, &is_swbp);
|
uprobe = find_active_uprobe(bp_vaddr, &is_swbp);
|
||||||
|
|
||||||
utask = current->utask;
|
|
||||||
if (utask)
|
|
||||||
utask->state = UTASK_RUNNING;
|
|
||||||
|
|
||||||
if (!uprobe) {
|
if (!uprobe) {
|
||||||
if (is_swbp > 0) {
|
if (is_swbp > 0) {
|
||||||
/* No matching uprobe; signal SIGTRAP. */
|
/* No matching uprobe; signal SIGTRAP. */
|
||||||
|
@ -1491,6 +1487,7 @@ static void handle_swbp(struct pt_regs *regs)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utask = current->utask;
|
||||||
if (!utask) {
|
if (!utask) {
|
||||||
utask = add_utask();
|
utask = add_utask();
|
||||||
/* Cannot allocate; re-execute the instruction. */
|
/* Cannot allocate; re-execute the instruction. */
|
||||||
|
@ -1547,13 +1544,12 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag. (and on
|
* On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag and
|
||||||
* subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and
|
* allows the thread to return from interrupt. After that handle_swbp()
|
||||||
* allows the thread to return from interrupt.
|
* sets utask->active_uprobe.
|
||||||
*
|
*
|
||||||
* On singlestep exception, singlestep notifier sets the TIF_UPROBE flag and
|
* On singlestep exception, singlestep notifier sets the TIF_UPROBE flag
|
||||||
* also sets the state to UTASK_SSTEP_ACK and allows the thread to return from
|
* and allows the thread to return from interrupt.
|
||||||
* interrupt.
|
|
||||||
*
|
*
|
||||||
* While returning to userspace, thread notices the TIF_UPROBE flag and calls
|
* While returning to userspace, thread notices the TIF_UPROBE flag and calls
|
||||||
* uprobe_notify_resume().
|
* uprobe_notify_resume().
|
||||||
|
@ -1563,10 +1559,10 @@ void uprobe_notify_resume(struct pt_regs *regs)
|
||||||
struct uprobe_task *utask;
|
struct uprobe_task *utask;
|
||||||
|
|
||||||
utask = current->utask;
|
utask = current->utask;
|
||||||
if (!utask || utask->state == UTASK_BP_HIT)
|
if (utask && utask->active_uprobe)
|
||||||
handle_swbp(regs);
|
|
||||||
else
|
|
||||||
handle_singlestep(utask, regs);
|
handle_singlestep(utask, regs);
|
||||||
|
else
|
||||||
|
handle_swbp(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1575,17 +1571,10 @@ void uprobe_notify_resume(struct pt_regs *regs)
|
||||||
*/
|
*/
|
||||||
int uprobe_pre_sstep_notifier(struct pt_regs *regs)
|
int uprobe_pre_sstep_notifier(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct uprobe_task *utask;
|
|
||||||
|
|
||||||
if (!current->mm || !test_bit(MMF_HAS_UPROBES, ¤t->mm->flags))
|
if (!current->mm || !test_bit(MMF_HAS_UPROBES, ¤t->mm->flags))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
utask = current->utask;
|
|
||||||
if (utask)
|
|
||||||
utask->state = UTASK_BP_HIT;
|
|
||||||
|
|
||||||
set_thread_flag(TIF_UPROBE);
|
set_thread_flag(TIF_UPROBE);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче