From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753910AbbIHHbY (ORCPT ); Tue, 8 Sep 2015 03:31:24 -0400 Received: from mail-wi0-f176.google.com ([209.85.212.176]:36925 "EHLO mail-wi0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753795AbbIHHbU (ORCPT ); Tue, 8 Sep 2015 03:31:20 -0400 Date: Tue, 8 Sep 2015 09:31:16 +0200 From: Ingo Molnar To: Thomas Gleixner Cc: Steven Rostedt , linux-kernel@vger.kernel.org, linux-rt-users , Carsten Emde , Sebastian Andrzej Siewior , John Kacur , Paul Gortmaker , Peter Zijlstra , Clark Williams , Arnaldo Carvalho de Melo Subject: Re: [RFC][PATCH RT 0/3] RT: Fix trylock deadlock without msleep() hack Message-ID: <20150908073116.GA6565@gmail.com> References: <20150904011900.730816481@goodmis.org> <20150905120457.GA21338@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org * Thomas Gleixner wrote: > 3) sched_yield() makes me shudder > > CPU0 CPU1 > > taskA > lock(x->lock) > > preemption > taskC > taskB > lock(y->lock); > x = y->x; > if (!try_lock(x->lock)) { > unlock(y->lock); > boost(taskA); > sched_yield(); <- returns immediately So I'm still struggling with properly parsing the usecase. If y->x might become invalid the moment we drop y->lock, what makes the 'taskA' use (after we've dropped y->lock) safe? Shouldn't we at least also have a task_get(taskA)/task_put(taskA) reference count, to make sure the boosted task stays around? And if we are into getting reference counts, why not solve it at a higher level and get a reference count to 'x' to make sure it's safe to use? Then we could do: lock(y->lock); retry: x = y->x; if (!trylock(x->lock)) { get_ref(x->count) unlock(y->lock); lock(x->lock); lock(y->lock); put_ref(x->count); if (y->x != x) { /* Retry if 'x' got dropped meanwhile */ unlock(x->lock); goto retry; } } Or so. Note how much safer this sequence is, and still just as fast in the common case (which I suppose is the main motivation within dcache.c?). Thanks, Ingo