| 1048 | } |
| 1049 | |
| 1050 | int |
| 1051 | _callout_stop_safe(struct callout *c, int flags, callout_func_t *drain) |
| 1052 | { |
| 1053 | struct callout_cpu *cc, *old_cc; |
| 1054 | struct lock_class *class; |
| 1055 | int direct, sq_locked, use_lock; |
| 1056 | int cancelled, not_on_a_list; |
| 1057 | |
| 1058 | if ((flags & CS_DRAIN) != 0) |
| 1059 | WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, c->c_lock, |
| 1060 | "calling %s", __func__); |
| 1061 | |
| 1062 | KASSERT((flags & CS_DRAIN) == 0 || drain == NULL, |
| 1063 | ("Cannot set drain callback and CS_DRAIN flag at the same time")); |
| 1064 | |
| 1065 | /* |
| 1066 | * Some old subsystems don't hold Giant while running a callout_stop(), |
| 1067 | * so just discard this check for the moment. |
| 1068 | */ |
| 1069 | if ((flags & CS_DRAIN) == 0 && c->c_lock != NULL) { |
| 1070 | if (c->c_lock == &Giant.lock_object) |
| 1071 | use_lock = mtx_owned(&Giant); |
| 1072 | else { |
| 1073 | use_lock = 1; |
| 1074 | class = LOCK_CLASS(c->c_lock); |
| 1075 | class->lc_assert(c->c_lock, LA_XLOCKED); |
| 1076 | } |
| 1077 | } else |
| 1078 | use_lock = 0; |
| 1079 | if (c->c_iflags & CALLOUT_DIRECT) { |
| 1080 | direct = 1; |
| 1081 | } else { |
| 1082 | direct = 0; |
| 1083 | } |
| 1084 | sq_locked = 0; |
| 1085 | old_cc = NULL; |
| 1086 | again: |
| 1087 | cc = callout_lock(c); |
| 1088 | |
| 1089 | if ((c->c_iflags & (CALLOUT_DFRMIGRATION | CALLOUT_PENDING)) == |
| 1090 | (CALLOUT_DFRMIGRATION | CALLOUT_PENDING) && |
| 1091 | ((c->c_flags & CALLOUT_ACTIVE) == CALLOUT_ACTIVE)) { |
| 1092 | /* |
| 1093 | * Special case where this slipped in while we |
| 1094 | * were migrating *as* the callout is about to |
| 1095 | * execute. The caller probably holds the lock |
| 1096 | * the callout wants. |
| 1097 | * |
| 1098 | * Get rid of the migration first. Then set |
| 1099 | * the flag that tells this code *not* to |
| 1100 | * try to remove it from any lists (its not |
| 1101 | * on one yet). When the callout wheel runs, |
| 1102 | * it will ignore this callout. |
| 1103 | */ |
| 1104 | c->c_iflags &= ~CALLOUT_PENDING; |
| 1105 | c->c_flags &= ~CALLOUT_ACTIVE; |
| 1106 | not_on_a_list = 1; |
| 1107 | } else { |
no test coverage detected