From owner-freebsd-arch@freebsd.org Thu Aug 24 16:41:11 2017 Return-Path: Delivered-To: freebsd-arch@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 374DFDE3CED for ; Thu, 24 Aug 2017 16:41:11 +0000 (UTC) (envelope-from truckman@FreeBSD.org) Received: from gw.catspoiler.org (unknown [IPv6:2602:304:b010:ef20::f2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "gw.catspoiler.org", Issuer "gw.catspoiler.org" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 17CED83C69; Thu, 24 Aug 2017 16:41:11 +0000 (UTC) (envelope-from truckman@FreeBSD.org) Received: from FreeBSD.org (mousie.catspoiler.org [192.168.101.2]) by gw.catspoiler.org (8.15.2/8.15.2) with ESMTP id v7OGf3pA042851; Thu, 24 Aug 2017 09:41:07 -0700 (PDT) (envelope-from truckman@FreeBSD.org) Message-Id: <201708241641.v7OGf3pA042851@gw.catspoiler.org> Date: Thu, 24 Aug 2017 09:41:03 -0700 (PDT) From: Don Lewis Subject: Re: ULE steal_idle questions To: avg@FreeBSD.org cc: freebsd-arch@FreeBSD.org In-Reply-To: MIME-Version: 1.0 Content-Type: TEXT/plain; charset=us-ascii X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Aug 2017 16:41:11 -0000 Aside from the Ryzen problem, I think the steal_idle code should be re-written so that it doesn't block interrupts for so long. In its current state, interrupt latence increases with the number of cores and the complexity of the topology. What I'm thinking is that we should set a flag at the start of the search for a thread to steal. If we are preempted by another, higher priority thread, that thread will clear the flag. Next we start the loop to search up the hierarchy. Once we find a candidate CPU: steal = TDQ_CPU(cpu); CPU_CLR(cpu, &mask); tdq_lock_pair(tdq, steal); if (tdq->tdq_load != 0) { goto out; /* to exit loop and switch to the new thread */ } if (flag was cleared) { tdq_unlock_pair(tdq, steal); goto restart; /* restart the search */ } if (steal->tdq_load < thresh || steal->tdq_transferable == 0 || tdq_move(steal, tdq) == 0) { tdq_unlock_pair(tdq, steal); continue; } out: TDQ_UNLOCK(steal); clear flag; mi_switch(SW_VOL | SWT_IDLE, NULL); thread_unlock(curthread); return (0); And we also have to clear the flag if we did not find a thread to steal.