diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-09-14 12:52:10 -0400 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2012-09-29 15:21:53 -0400 |
commit | 1b08e907211cdc744f54871736005d9f3e7f182c (patch) | |
tree | df62046438501ecd89e0bac1fb9b73edaf622e15 | |
parent | 0578a97098dab967ece4b025fe5eb4984c4c86c0 (diff) |
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>
-rw-r--r-- | include/linux/uprobes.h | 1 | ||||
-rw-r--r-- | kernel/events/uprobes.c | 29 |
2 files changed, 9 insertions, 21 deletions
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index e6f0331e3d45..18d839da6517 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h | |||
@@ -59,7 +59,6 @@ struct uprobe_consumer { | |||
59 | #ifdef CONFIG_UPROBES | 59 | #ifdef CONFIG_UPROBES |
60 | enum uprobe_task_state { | 60 | enum uprobe_task_state { |
61 | UTASK_RUNNING, | 61 | UTASK_RUNNING, |
62 | UTASK_BP_HIT, | ||
63 | UTASK_SSTEP, | 62 | UTASK_SSTEP, |
64 | UTASK_SSTEP_ACK, | 63 | UTASK_SSTEP_ACK, |
65 | UTASK_SSTEP_TRAPPED, | 64 | UTASK_SSTEP_TRAPPED, |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index d2392968d4e6..d3f5381e7482 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1469,10 +1469,6 @@ static void handle_swbp(struct pt_regs *regs) | |||
1469 | bp_vaddr = uprobe_get_swbp_addr(regs); | 1469 | bp_vaddr = uprobe_get_swbp_addr(regs); |
1470 | uprobe = find_active_uprobe(bp_vaddr, &is_swbp); | 1470 | uprobe = find_active_uprobe(bp_vaddr, &is_swbp); |
1471 | 1471 | ||
1472 | utask = current->utask; | ||
1473 | if (utask) | ||
1474 | utask->state = UTASK_RUNNING; | ||
1475 | |||
1476 | if (!uprobe) { | 1472 | if (!uprobe) { |
1477 | if (is_swbp > 0) { | 1473 | if (is_swbp > 0) { |
1478 | /* No matching uprobe; signal SIGTRAP. */ | 1474 | /* No matching uprobe; signal SIGTRAP. */ |
@@ -1491,6 +1487,7 @@ static void handle_swbp(struct pt_regs *regs) | |||
1491 | return; | 1487 | return; |
1492 | } | 1488 | } |
1493 | 1489 | ||
1490 | utask = current->utask; | ||
1494 | if (!utask) { | 1491 | if (!utask) { |
1495 | utask = add_utask(); | 1492 | utask = add_utask(); |
1496 | /* Cannot allocate; re-execute the instruction. */ | 1493 | /* Cannot allocate; re-execute the instruction. */ |
@@ -1547,13 +1544,12 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs) | |||
1547 | } | 1544 | } |
1548 | 1545 | ||
1549 | /* | 1546 | /* |
1550 | * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag. (and on | 1547 | * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag and |
1551 | * subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and | 1548 | * allows the thread to return from interrupt. After that handle_swbp() |
1552 | * allows the thread to return from interrupt. | 1549 | * sets utask->active_uprobe. |
1553 | * | 1550 | * |
1554 | * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag and | 1551 | * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag |
1555 | * also sets the state to UTASK_SSTEP_ACK and allows the thread to return from | 1552 | * and allows the thread to return from interrupt. |
1556 | * interrupt. | ||
1557 | * | 1553 | * |
1558 | * While returning to userspace, thread notices the TIF_UPROBE flag and calls | 1554 | * While returning to userspace, thread notices the TIF_UPROBE flag and calls |
1559 | * uprobe_notify_resume(). | 1555 | * uprobe_notify_resume(). |
@@ -1563,10 +1559,10 @@ void uprobe_notify_resume(struct pt_regs *regs) | |||
1563 | struct uprobe_task *utask; | 1559 | struct uprobe_task *utask; |
1564 | 1560 | ||
1565 | utask = current->utask; | 1561 | utask = current->utask; |
1566 | if (!utask || utask->state == UTASK_BP_HIT) | 1562 | if (utask && utask->active_uprobe) |
1567 | handle_swbp(regs); | ||
1568 | else | ||
1569 | handle_singlestep(utask, regs); | 1563 | handle_singlestep(utask, regs); |
1564 | else | ||
1565 | handle_swbp(regs); | ||
1570 | } | 1566 | } |
1571 | 1567 | ||
1572 | /* | 1568 | /* |
@@ -1575,17 +1571,10 @@ void uprobe_notify_resume(struct pt_regs *regs) | |||
1575 | */ | 1571 | */ |
1576 | int uprobe_pre_sstep_notifier(struct pt_regs *regs) | 1572 | int uprobe_pre_sstep_notifier(struct pt_regs *regs) |
1577 | { | 1573 | { |
1578 | struct uprobe_task *utask; | ||
1579 | |||
1580 | if (!current->mm || !test_bit(MMF_HAS_UPROBES, ¤t->mm->flags)) | 1574 | if (!current->mm || !test_bit(MMF_HAS_UPROBES, ¤t->mm->flags)) |
1581 | return 0; | 1575 | return 0; |
1582 | 1576 | ||
1583 | utask = current->utask; | ||
1584 | if (utask) | ||
1585 | utask->state = UTASK_BP_HIT; | ||
1586 | |||
1587 | set_thread_flag(TIF_UPROBE); | 1577 | set_thread_flag(TIF_UPROBE); |
1588 | |||
1589 | return 1; | 1578 | return 1; |
1590 | } | 1579 | } |
1591 | 1580 | ||