The old thread priority must be stored as part of the EPOCH(9) tracker.

Else recursive use of EPOCH(9) may cause the wrong priority to be restored.

Bump the __FreeBSD_version due to changing the thread and epoch tracker
structure.

Differential Revision:	https://reviews.freebsd.org/D30375
Reviewed by:	markj@
MFC after:	1 week
Sponsored by:	Mellanox Technologies // NVIDIA Networking
This commit is contained in:
Hans Petter Selasky 2021-05-21 10:27:20 +02:00
parent c50346bcf5
commit ef0f7ae934
4 changed files with 5 additions and 5 deletions

View File

@ -457,7 +457,7 @@ _epoch_enter_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE)
THREAD_NO_SLEEPING(); THREAD_NO_SLEEPING();
critical_enter(); critical_enter();
sched_pin(); sched_pin();
td->td_pre_epoch_prio = td->td_priority; et->et_old_priority = td->td_priority;
er = epoch_currecord(epoch); er = epoch_currecord(epoch);
/* Record-level tracking is reserved for non-preemptible epochs. */ /* Record-level tracking is reserved for non-preemptible epochs. */
MPASS(er->er_td == NULL); MPASS(er->er_td == NULL);
@ -510,8 +510,8 @@ _epoch_exit_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE)
ck_epoch_end(&er->er_record, &et->et_section); ck_epoch_end(&er->er_record, &et->et_section);
TAILQ_REMOVE(&er->er_tdlist, et, et_link); TAILQ_REMOVE(&er->er_tdlist, et, et_link);
er->er_gen++; er->er_gen++;
if (__predict_false(td->td_pre_epoch_prio != td->td_priority)) if (__predict_false(et->et_old_priority != td->td_priority))
epoch_adjust_prio(td, td->td_pre_epoch_prio); epoch_adjust_prio(td, et->et_old_priority);
critical_exit(); critical_exit();
#ifdef EPOCH_TRACE #ifdef EPOCH_TRACE
epoch_trace_exit(td, epoch, et, file, line); epoch_trace_exit(td, epoch, et, file, line);

View File

@ -55,6 +55,7 @@ struct epoch_tracker {
TAILQ_ENTRY(epoch_tracker) et_link; TAILQ_ENTRY(epoch_tracker) et_link;
struct thread *et_td; struct thread *et_td;
ck_epoch_section_t et_section; ck_epoch_section_t et_section;
uint8_t et_old_priority;
#ifdef EPOCH_TRACE #ifdef EPOCH_TRACE
struct epoch *et_epoch; struct epoch *et_epoch;
SLIST_ENTRY(epoch_tracker) et_tlink; SLIST_ENTRY(epoch_tracker) et_tlink;

View File

@ -76,7 +76,7 @@
* cannot include sys/param.h and should only be updated here. * cannot include sys/param.h and should only be updated here.
*/ */
#undef __FreeBSD_version #undef __FreeBSD_version
#define __FreeBSD_version 1400013 #define __FreeBSD_version 1400014
/* /*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View File

@ -325,7 +325,6 @@ struct thread {
u_char td_pri_class; /* (t) Scheduling class. */ u_char td_pri_class; /* (t) Scheduling class. */
u_char td_user_pri; /* (t) User pri from estcpu and nice. */ u_char td_user_pri; /* (t) User pri from estcpu and nice. */
u_char td_base_user_pri; /* (t) Base user pri */ u_char td_base_user_pri; /* (t) Base user pri */
u_char td_pre_epoch_prio; /* (k) User pri on entry to epoch */
uintptr_t td_rb_list; /* (k) Robust list head. */ uintptr_t td_rb_list; /* (k) Robust list head. */
uintptr_t td_rbp_list; /* (k) Robust priv list head. */ uintptr_t td_rbp_list; /* (k) Robust priv list head. */
uintptr_t td_rb_inact; /* (k) Current in-action mutex loc. */ uintptr_t td_rb_inact; /* (k) Current in-action mutex loc. */