| 789 | } |
| 790 | |
| 791 | int |
| 792 | _callout_stop_safe(struct callout *c, int flags, void (*drain)(void *)) |
| 793 | { |
| 794 | struct callout_cpu *cc, *old_cc; |
| 795 | struct lock_class *class; |
| 796 | int direct, sq_locked, use_lock; |
| 797 | int cancelled, not_on_a_list; |
| 798 | |
| 799 | if ((flags & CS_DRAIN) != 0) |
| 800 | WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, c->c_lock, |
| 801 | "calling %s", __func__); |
| 802 | |
| 803 | /* |
| 804 | * Some old subsystems don't hold Giant while running a callout_stop(), |
| 805 | * so just discard this check for the moment. |
| 806 | */ |
| 807 | if ((flags & CS_DRAIN) == 0 && c->c_lock != NULL) { |
| 808 | if (c->c_lock == &Giant.lock_object) |
| 809 | use_lock = mtx_owned(&Giant); |
| 810 | else { |
| 811 | use_lock = 1; |
| 812 | class = LOCK_CLASS(c->c_lock); |
| 813 | class->lc_assert(c->c_lock, LA_XLOCKED); |
| 814 | } |
| 815 | } else |
| 816 | use_lock = 0; |
| 817 | if (c->c_iflags & CALLOUT_DIRECT) { |
| 818 | direct = 1; |
| 819 | } else { |
| 820 | direct = 0; |
| 821 | } |
| 822 | sq_locked = 0; |
| 823 | old_cc = NULL; |
| 824 | again: |
| 825 | cc = callout_lock(c); |
| 826 | |
| 827 | if ((c->c_iflags & (CALLOUT_DFRMIGRATION | CALLOUT_PENDING)) == |
| 828 | (CALLOUT_DFRMIGRATION | CALLOUT_PENDING) && |
| 829 | ((c->c_flags & CALLOUT_ACTIVE) == CALLOUT_ACTIVE)) { |
| 830 | /* |
| 831 | * Special case where this slipped in while we |
| 832 | * were migrating *as* the callout is about to |
| 833 | * execute. The caller probably holds the lock |
| 834 | * the callout wants. |
| 835 | * |
| 836 | * Get rid of the migration first. Then set |
| 837 | * the flag that tells this code *not* to |
| 838 | * try to remove it from any lists (its not |
| 839 | * on one yet). When the callout wheel runs, |
| 840 | * it will ignore this callout. |
| 841 | */ |
| 842 | c->c_iflags &= ~CALLOUT_PENDING; |
| 843 | c->c_flags &= ~CALLOUT_ACTIVE; |
| 844 | not_on_a_list = 1; |
| 845 | } else { |
| 846 | not_on_a_list = 0; |
| 847 | } |
| 848 |
nothing calls this directly
no test coverage detected