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:
Oleg Nesterov 2012-09-14 18:52:10 +02:00
Родитель 0578a97098
Коммит 1b08e90721
2 изменённых файлов: 9 добавлений и 21 удалений

Просмотреть файл

@ -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, &current->mm->flags)) if (!current->mm || !test_bit(MMF_HAS_UPROBES, &current->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;
} }