Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Feb 2017 20:55:04 +0100
From:      "O. Hartmann" <ohartmann@walstatt.org>
To:        Ryan Stone <rstone@FreeBSD.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r313814 - head/sys/kern
Message-ID:  <20170216205455.4db475b0@thor.intern.walstatt.dynvpn.de>
In-Reply-To: <201702161941.v1GJfDoP087457@repo.freebsd.org>
References:  <201702161941.v1GJfDoP087457@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
--Sig_/Jl9eb+ySX0Of77FrF3jqqL9
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Am Thu, 16 Feb 2017 19:41:13 +0000 (UTC)
Ryan Stone <rstone@FreeBSD.org> schrieb:

> Author: rstone
> Date: Thu Feb 16 19:41:13 2017
> New Revision: 313814
> URL: https://svnweb.freebsd.org/changeset/base/313814
>=20
> Log:
>   Check for preemption after lowering a thread's priority
>  =20
>   When a high-priority thread is waiting for a mutex held by a
>   low-priority thread, it temporarily lends its priority to the
>   low-priority thread to prevent priority inversion.  When the mutex
>   is released, the lent priority is revoked and the low-priority
>   thread goes back to its original priority.
>  =20
>   When the priority of that thread is lowered (through a call to
>   sched_priority()), the schedule was not checking whether
>   there is now a high-priority thread in the run queue.  This can
>   cause threads with real-time priority to be starved in the run
>   queue while the low-priority thread finishes its quantum.
>  =20
>   Fix this by explicitly checking whether preemption is necessary
>   when a thread's priority is lowered.
>  =20
>   Sponsored by: Dell EMC Isilon
>   Obtained from: Sandvine Inc
>   Differential Revision:	https://reviews.freebsd.org/D9518
>   Reviewed by: Jeff Roberson (ule)
>   MFC after: 1 month
>=20
> Modified:
>   head/sys/kern/sched_4bsd.c
>   head/sys/kern/sched_ule.c
>=20
> Modified: head/sys/kern/sched_4bsd.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/sys/kern/sched_4bsd.c	Thu Feb 16 19:00:09 2017	(r313813)
> +++ head/sys/kern/sched_4bsd.c	Thu Feb 16 19:41:13 2017	(r313814)
> @@ -816,7 +816,12 @@ sched_class(struct thread *td, int class
>  static void
>  sched_priority(struct thread *td, u_char prio)
>  {
> -
> +	struct thread *newtd;
> +	struct runq *rq;
> +	u_char orig_pri;
> +#ifdef SMP
> +	struct thread *cputd;
> +#endif
> =20
>  	KTR_POINT3(KTR_SCHED, "thread", sched_tdname(td), "priority change",
>  	    "prio:%d", td->td_priority, "new prio:%d", prio, KTR_ATTR_LINKED,
> @@ -832,10 +837,43 @@ sched_priority(struct thread *td, u_char
>  	THREAD_LOCK_ASSERT(td, MA_OWNED);
>  	if (td->td_priority =3D=3D prio)
>  		return;
> +	orig_pri =3D td->td_priority;
>  	td->td_priority =3D prio;
>  	if (TD_ON_RUNQ(td) && td->td_rqindex !=3D (prio / RQ_PPQ)) {
>  		sched_rem(td);
>  		sched_add(td, SRQ_BORING);
> +	} else if (orig_pri < prio && TD_IS_RUNNING(td)) {
> +		/*
> +		 * If we have decreased the priority of a running thread, we
> +		 * have to check if it should be preempted.
> +		 */
> +		rq =3D &runq;
> +		newtd =3D runq_choose(&runq);
> +#ifdef SMP
> +		cputd =3D runq_choose(&runq_pcpu[td->td_oncpu]);
> +		if (newtd =3D=3D NULL ||
> +		    (cputd !=3D NULL && cputd->td_priority < td->td_priority))
> +			newtd =3D cputd;
> +#endif
> +
> +		if (newtd !=3D NULL && newtd->td_priority < prio
> +#ifndef FULL_PREEMPTION
> +		    && (newtd->td_priority <=3D PRI_MAX_ITHD ||
> +		        prio >=3D PRI_MIN_IDLE))
> +#endif
> +		) {
> +			if (td =3D=3D curthread)
> +				/*
> +				 * Don't reschedule the thread here as it may
> +				 * be losing priority because it has released a
> +				 * mutex, and in that case we need it to finish
> +				 * releasing the lock before it gets preempted.
> +				 */
> +				td->td_owepreempt =3D 1;
> +			else
> +				kick_other_cpu(newtd->td_priority,
> +				    td->td_oncpu);
> +		}
>  	}
>  }
> =20
>=20
> Modified: head/sys/kern/sched_ule.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/sys/kern/sched_ule.c	Thu Feb 16 19:00:09 2017	(r313813)
> +++ head/sys/kern/sched_ule.c	Thu Feb 16 19:41:13 2017	(r313814)
> @@ -319,7 +319,7 @@ static void tdq_add(struct tdq *, struct
>  #ifdef SMP
>  static int tdq_move(struct tdq *, struct tdq *);
>  static int tdq_idled(struct tdq *);
> -static void tdq_notify(struct tdq *, struct thread *);
> +static void tdq_notify(struct tdq *, int);
>  static struct thread *tdq_steal(struct tdq *, int);
>  static struct thread *runq_steal(struct runq *, int);
>  static int sched_pickcpu(struct thread *, int);
> @@ -1040,16 +1040,14 @@ tdq_idled(struct tdq *tdq)
>   * Notify a remote cpu of new work.  Sends an IPI if criteria are met.
>   */
>  static void
> -tdq_notify(struct tdq *tdq, struct thread *td)
> +tdq_notify(struct tdq *tdq, int pri)
>  {
>  	struct thread *ctd;
> -	int pri;
>  	int cpu;
> =20
>  	if (tdq->tdq_ipipending)
>  		return;
> -	cpu =3D td_get_sched(td)->ts_cpu;
> -	pri =3D td->td_priority;
> +	cpu =3D TD_ID(tdq);
>  	ctd =3D pcpu_find(cpu)->pc_curthread;
>  	if (!sched_shouldpreempt(pri, ctd->td_priority, 1))
>  		return;
> @@ -1675,6 +1673,22 @@ sched_pctcpu_update(struct td_sched *ts,
>  	ts->ts_ltick =3D t;
>  }
> =20
> +static void
> +sched_check_preempt(struct tdq *tdq, struct thread *td)
> +{
> +
> +	KASSERT(TD_IS_RUNNING(td), ("thread is not running"));
> +	TDQ_LOCK_ASSERT(tdq, MA_OWNED);
> +	KASSERT(tdq =3D=3D TDQ_CPU(td->td_sched->ts_cpu),
> +	    ("tdq does not contain td"));
> +
> +	if (tdq =3D=3D TDQ_SELF()) {
> +		if (sched_shouldpreempt(tdq->tdq_lowpri, td->td_priority, 0))
> +			td->td_owepreempt =3D 1;
> +	} else
> +		tdq_notify(tdq, tdq->tdq_lowpri);
> +}
> +
>  /*
>   * Adjust the priority of a thread.  Move it to the appropriate run-queue
>   * if necessary.  This is the back-end for several priority related
> @@ -1726,6 +1740,9 @@ sched_thread_priority(struct thread *td,
>  			tdq->tdq_lowpri =3D prio;
>  		else if (tdq->tdq_lowpri =3D=3D oldpri)
>  			tdq_setlowpri(tdq, td);
> +
> +		if (oldpri < prio)
> +			sched_check_preempt(tdq, td);
>  		return;
>  	}
>  	td->td_priority =3D prio;
> @@ -1854,7 +1871,7 @@ sched_switch_migrate(struct tdq *tdq, st
>  	 */
>  	tdq_lock_pair(tdn, tdq);
>  	tdq_add(tdn, td, flags);
> -	tdq_notify(tdn, td);
> +	tdq_notify(tdn, td->td_priority);
>  	TDQ_UNLOCK(tdn);
>  	spinlock_exit();
>  #endif
> @@ -2429,7 +2446,7 @@ sched_add(struct thread *td, int flags)
>  	tdq =3D sched_setcpu(td, cpu, flags);
>  	tdq_add(tdq, td, flags);
>  	if (cpu !=3D PCPU_GET(cpuid)) {
> -		tdq_notify(tdq, td);
> +		tdq_notify(tdq, td->td_priority);
>  		return;
>  	}
>  #else
> _______________________________________________
> svn-src-head@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscribe@freebsd.org"

 This commit breaks buildkernel:

--- sched_ule.o ---
/usr/src/sys/kern/sched_ule.c:1050:8: error: implicit declaration of functi=
on 'TD_ID' is
invalid in C99 [-Werror,-Wimplicit-function-declaration] cpu =3D TD_ID(tdq);
              ^
1 error generated.
*** [sched_ule.o] Error code 1

--=20
O. Hartmann

Ich widerspreche der Nutzung oder =C3=9Cbermittlung meiner Daten f=C3=BCr
Werbezwecke oder f=C3=BCr die Markt- oder Meinungsforschung (=C2=A7 28 Abs.=
 4 BDSG).

--Sig_/Jl9eb+ySX0Of77FrF3jqqL9
Content-Type: application/pgp-signature
Content-Description: OpenPGP digital signature

-----BEGIN PGP SIGNATURE-----

iLUEARMKAB0WIQQZVZMzAtwC2T/86TrS528fyFhYlAUCWKYDmAAKCRDS528fyFhY
lCvKAfwL0yNbn5U6omEHedcfA5dUPaFaLLHp7IdMZNH6VWYiGNOPLcP5Jg86Xd5l
K26dloHO3ULOsr0D8KWGVY9lv/mQAf4gZkEauEhlQ0R1xkh89WPtmdVWC0UES+gZ
/0QzDezNvUqdwOOe+bqpiwU6SDGRz2ak2W30y9ra/Uq1XfWWXA1p
=cqpf
-----END PGP SIGNATURE-----

--Sig_/Jl9eb+ySX0Of77FrF3jqqL9--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170216205455.4db475b0>