Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_rmlock.c
| Show First 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | unlock_rm(struct lock_object *lock) | ||||
| else { | else { | ||||
| /* | /* | ||||
| * Find the right rm_priotracker structure for curthread. | * Find the right rm_priotracker structure for curthread. | ||||
| * The guarantee about its uniqueness is given by the fact | * The guarantee about its uniqueness is given by the fact | ||||
| * we already asserted the lock wasn't recursively acquired. | * we already asserted the lock wasn't recursively acquired. | ||||
| */ | */ | ||||
| critical_enter(); | critical_enter(); | ||||
| td = curthread; | td = curthread; | ||||
| pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
| for (queue = pc->pc_rm_queue.rmq_next; | for (queue = pc->pc_rm_queue.rmq_next; | ||||
| queue != &pc->pc_rm_queue; queue = queue->rmq_next) { | queue != &pc->pc_rm_queue; queue = queue->rmq_next) { | ||||
| tracker = (struct rm_priotracker *)queue; | tracker = (struct rm_priotracker *)queue; | ||||
| if ((tracker->rmp_rmlock == rm) && | if ((tracker->rmp_rmlock == rm) && | ||||
| (tracker->rmp_thread == td)) { | (tracker->rmp_thread == td)) { | ||||
| how = (uintptr_t)tracker; | how = (uintptr_t)tracker; | ||||
| break; | break; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
| static void | static void | ||||
| rm_cleanIPI(void *arg) | rm_cleanIPI(void *arg) | ||||
| { | { | ||||
| struct pcpu *pc; | struct pcpu *pc; | ||||
| struct rmlock *rm = arg; | struct rmlock *rm = arg; | ||||
| struct rm_priotracker *tracker; | struct rm_priotracker *tracker; | ||||
| struct rm_queue *queue; | struct rm_queue *queue; | ||||
| pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
| for (queue = pc->pc_rm_queue.rmq_next; queue != &pc->pc_rm_queue; | for (queue = pc->pc_rm_queue.rmq_next; queue != &pc->pc_rm_queue; | ||||
| queue = queue->rmq_next) { | queue = queue->rmq_next) { | ||||
| tracker = (struct rm_priotracker *)queue; | tracker = (struct rm_priotracker *)queue; | ||||
| if (tracker->rmp_rmlock == rm && tracker->rmp_flags == 0) { | if (tracker->rmp_rmlock == rm && tracker->rmp_flags == 0) { | ||||
| tracker->rmp_flags = RMPF_ONQUEUE; | tracker->rmp_flags = RMPF_ONQUEUE; | ||||
| mtx_lock_spin(&rm_spinlock); | mtx_lock_spin(&rm_spinlock); | ||||
| LIST_INSERT_HEAD(&rm->rm_activeReaders, tracker, | LIST_INSERT_HEAD(&rm->rm_activeReaders, tracker, | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static int | static int | ||||
| _rm_rlock_hard(struct rmlock *rm, struct rm_priotracker *tracker, int trylock) | _rm_rlock_hard(struct rmlock *rm, struct rm_priotracker *tracker, int trylock) | ||||
| { | { | ||||
| struct pcpu *pc; | struct pcpu *pc; | ||||
| critical_enter(); | critical_enter(); | ||||
| pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
| /* Check if we just need to do a proper critical_exit. */ | /* Check if we just need to do a proper critical_exit. */ | ||||
| if (!CPU_ISSET(pc->pc_cpuid, &rm->rm_writecpus)) { | if (!CPU_ISSET(pc->pc_cpuid, &rm->rm_writecpus)) { | ||||
| critical_exit(); | critical_exit(); | ||||
| return (1); | return (1); | ||||
| } | } | ||||
| /* Remove our tracker from the per-cpu list. */ | /* Remove our tracker from the per-cpu list. */ | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | if (rm->lock_object.lo_flags & LO_SLEEPABLE) { | ||||
| THREAD_SLEEPING_OK(); | THREAD_SLEEPING_OK(); | ||||
| sx_xlock(&rm->rm_lock_sx); | sx_xlock(&rm->rm_lock_sx); | ||||
| THREAD_NO_SLEEPING(); | THREAD_NO_SLEEPING(); | ||||
| } else | } else | ||||
| mtx_lock(&rm->rm_lock_mtx); | mtx_lock(&rm->rm_lock_mtx); | ||||
| } | } | ||||
| critical_enter(); | critical_enter(); | ||||
| pc = pcpu_find(curcpu); | pc = get_pcpu(); | ||||
| CPU_CLR(pc->pc_cpuid, &rm->rm_writecpus); | CPU_CLR(pc->pc_cpuid, &rm->rm_writecpus); | ||||
| rm_tracker_add(pc, tracker); | rm_tracker_add(pc, tracker); | ||||
| sched_pin(); | sched_pin(); | ||||
| critical_exit(); | critical_exit(); | ||||
| if (rm->lock_object.lo_flags & LO_SLEEPABLE) | if (rm->lock_object.lo_flags & LO_SLEEPABLE) | ||||
| sx_xunlock(&rm->rm_lock_sx); | sx_xunlock(&rm->rm_lock_sx); | ||||
| else | else | ||||
| ▲ Show 20 Lines • Show All 208 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| if (SCHEDULER_STOPPED()) | if (SCHEDULER_STOPPED()) | ||||
| return (1); | return (1); | ||||
| #ifdef INVARIANTS | #ifdef INVARIANTS | ||||
| if (!(rm->lock_object.lo_flags & LO_RECURSABLE) && !trylock) { | if (!(rm->lock_object.lo_flags & LO_RECURSABLE) && !trylock) { | ||||
| critical_enter(); | critical_enter(); | ||||
| KASSERT(rm_trackers_present(pcpu_find(curcpu), rm, | KASSERT(rm_trackers_present(get_pcpu(), rm, | ||||
| curthread) == 0, | curthread) == 0, | ||||
| ("rm_rlock: recursed on non-recursive rmlock %s @ %s:%d\n", | ("rm_rlock: recursed on non-recursive rmlock %s @ %s:%d\n", | ||||
| rm->lock_object.lo_name, file, line)); | rm->lock_object.lo_name, file, line)); | ||||
| critical_exit(); | critical_exit(); | ||||
| } | } | ||||
| #endif | #endif | ||||
| KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), | KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), | ||||
| ("rm_rlock() by idle thread %p on rmlock %s @ %s:%d", | ("rm_rlock() by idle thread %p on rmlock %s @ %s:%d", | ||||
| ▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | if (rm_wowned(rm)) { | ||||
| rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
| if (what & RA_RECURSED) | if (what & RA_RECURSED) | ||||
| panic("Lock %s not recursed @ %s:%d\n", | panic("Lock %s not recursed @ %s:%d\n", | ||||
| rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
| break; | break; | ||||
| } | } | ||||
| critical_enter(); | critical_enter(); | ||||
| count = rm_trackers_present(pcpu_find(curcpu), rm, curthread); | count = rm_trackers_present(get_pcpu(), rm, curthread); | ||||
| critical_exit(); | critical_exit(); | ||||
| if (count == 0) | if (count == 0) | ||||
| panic("Lock %s not %slocked @ %s:%d\n", | panic("Lock %s not %slocked @ %s:%d\n", | ||||
| rm->lock_object.lo_name, (what & RA_RLOCKED) ? | rm->lock_object.lo_name, (what & RA_RLOCKED) ? | ||||
| "read " : "", file, line); | "read " : "", file, line); | ||||
| if (count > 1) { | if (count > 1) { | ||||
| if (what & RA_NOTRECURSED) | if (what & RA_NOTRECURSED) | ||||
| Show All 9 Lines | if (!rm_wowned(rm)) | ||||
| rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
| break; | break; | ||||
| case RA_UNLOCKED: | case RA_UNLOCKED: | ||||
| if (rm_wowned(rm)) | if (rm_wowned(rm)) | ||||
| panic("Lock %s exclusively locked @ %s:%d\n", | panic("Lock %s exclusively locked @ %s:%d\n", | ||||
| rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
| critical_enter(); | critical_enter(); | ||||
| count = rm_trackers_present(pcpu_find(curcpu), rm, curthread); | count = rm_trackers_present(get_pcpu(), rm, curthread); | ||||
| critical_exit(); | critical_exit(); | ||||
| if (count != 0) | if (count != 0) | ||||
| panic("Lock %s read locked @ %s:%d\n", | panic("Lock %s read locked @ %s:%d\n", | ||||
| rm->lock_object.lo_name, file, line); | rm->lock_object.lo_name, file, line); | ||||
| break; | break; | ||||
| default: | default: | ||||
| panic("Unknown rm lock assertion: %d @ %s:%d", what, file, | panic("Unknown rm lock assertion: %d @ %s:%d", what, file, | ||||
| ▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines | |||||