From owner-freebsd-arch@FreeBSD.ORG Tue Sep 18 12:59:24 2012 Return-Path: Delivered-To: arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4D712106564A for ; Tue, 18 Sep 2012 12:59:24 +0000 (UTC) (envelope-from phk@phk.freebsd.dk) Received: from phk.freebsd.dk (phk.freebsd.dk [130.225.244.222]) by mx1.freebsd.org (Postfix) with ESMTP id 0D10C8FC0A for ; Tue, 18 Sep 2012 12:59:23 +0000 (UTC) Received: from critter.freebsd.dk (unknown [192.168.61.3]) by phk.freebsd.dk (Postfix) with ESMTP id F21923B79D for ; Tue, 18 Sep 2012 12:59:21 +0000 (UTC) Received: from critter.freebsd.dk (localhost [127.0.0.1]) by critter.freebsd.dk (8.14.5/8.14.5) with ESMTP id q8ICxKiY095609 for ; Tue, 18 Sep 2012 12:59:21 GMT (envelope-from phk@phk.freebsd.dk) To: arch@freebsd.org From: Poul-Henning Kamp Content-Type: text/plain; charset=ISO-8859-1 Date: Tue, 18 Sep 2012 12:59:20 +0000 Message-ID: <95608.1347973160@critter.freebsd.dk> Cc: Subject: Aliasing issue with TAILQ on ppc64 ? X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Sep 2012 12:59:24 -0000 In Varnish I have adopted and today I saw a weird issue on a PPC64 platform, which makes me wonder if we have a potential aliasing issue with TAILQs. The backwards pointers in TAILQs point to the forward pointer of the previous element, rather than to the top of the previous element. To go backwards you therefore have to go two steps backwards and one step forward. TAILQ_PREV and TAILQ_LAST do this by assuming that the head and element structures for a TAILQ are the same, and casts the point from &(elem->next) to &head, and dereferences head->last as a proxy for elem->prev. This is elegant, but not type-safe. I have not 100% confirmed, that in the in problem we had with PPC64, the compiler in this case fails to spot the aliasing. When I made the head-struct volatile, the problem went away, which it also did when I put in a function call at the suspect place to force a register spill. I have previously tried to find a way to rewrite TAILQ_LAST/PREV to be type-safe, but utterly failed, and I have reached the conclusion that with the current "API" or minor modifications thereof, that is patently impossible. It may be a good idea to find some way to make sure the compiler spots the potential aliasing, but I am not sufficiently up to date on compiler optimizations to know a safe and reliable way to do that. (Would explicitly casting throuh a void do it ?) Poul-Henning Details: https://github.com/varnish/Varnish-Cache/blob/3.0/bin/varnishd/cache_ban.c lines 388-393. The problem happens on startup, when the ban_head list is empty, and I belive the issue is that the (V)TAILQ_INSERT_HEAD() has not stored the head->last pointer, by the time the (V)TAILQ_LAST() tries to dereference it, and that the compiler does not spot the aliasing. -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk@FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence.