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 /kernel | |
| 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>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/events/uprobes.c | 29 |
1 files changed, 9 insertions, 20 deletions
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 | ||
