From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.2 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 9631E1F55B for ; Fri, 29 May 2020 09:40:37 +0000 (UTC) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2FCFF3982C28; Fri, 29 May 2020 09:40:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2FCFF3982C28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1590745236; bh=STK1/lxYxb4b9koAe3GfJTddoRICIDLdJMIVPeabVtU=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=p1czA488IpeaRC2yVncz1xkCrzd6OziApQmqLlNCMkfbwqrxEPj84uznauDCstT8F an3s28iWIkLHi7IircMfDhMwZoUXHfePffPuJ0CHD4wdZBAU1M1/6gvCpFLuDgKX3i 1CcNUG/zHA5TfEsgTmgRXg4Vs6ASY2fEKvyb6iC8= Received: from smtp.gentoo.org (dev.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) by sourceware.org (Postfix) with ESMTP id 3EF163982C69 for ; Fri, 29 May 2020 09:40:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3EF163982C69 Date: Fri, 29 May 2020 10:40:19 +0100 To: sparclinux@vger.kernel.org, libc-alpha@sourceware.org Subject: sparc vs sparc64: O_NDELAY and O_NONBLOCK mismatch in kernel and in glibc Message-ID: <20200529104019.72983ef9@sf> X-Mailer: Claws Mail 3.17.5 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergei Trofimovich via Libc-alpha Reply-To: Sergei Trofimovich Cc: sparc@gentoo.org, "David S. Miller" , =?UTF-8?B?TWljaGHFgiBHw7Nybnk=?= , toolchain@gentoo.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" On most targets glibc defines O_NDELAY as O_NONBLOCK. glibc's manual/llio.texi manual says they are supposed to be equal: """ @deftypevr Macro int O_NDELAY @standards{BSD, fcntl.h} This is an obsolete name for @code{O_NONBLOCK}, provided for compatibility with BSD. It is not defined by the POSIX.1 standard. @end deftypevr """ A bunch of packages rely on it and find out that this assumption breaks on sparc in unusual ways. Recently it popped up as: https://github.com/eventlet/eventlet/pull/615 Older workarounds: https://github.com/libuv/libuv/issues/1830 What is more confusing for me: linux kernel's uapi definition of O_NDELAY is ABI-dependent: arch/sparc/include/uapi/asm/fcntl.h """ #if defined(__sparc__) && defined(__arch64__) #define O_NDELAY 0x0004 #else #define O_NDELAY (0x0004 | O_NONBLOCK) #endif """ while glibc's is not: sysdeps/unix/sysv/linux/sparc/bits/fcntl.h """ #define O_NONBLOCK 0x4000 #define O_NDELAY (0x0004 | O_NONBLOCK) """ Spot-checking preprocessor's output that seems to corroborate: """ $ printf "#include '\n int o_ndelay = O_NDELAY; int o_nonblock = O_NONBLOCK;" | sparc-unknown-linux-gnu-gcc -E -x c - | fgrep -A3 o_ int o_ndelay = (0x0004 | 0x4000) ; int o_nonblock = 0x4000 $ printf "#include '\n int o_ndelay = O_NDELAY; int o_nonblock = O_NONBLOCK;" | sparc64-unknown-linux-gnu-gcc -E -x c - | fgrep -A3 o_ int o_ndelay = (0x0004 | 0x4000) ; int o_nonblock = 0x4000 """ I think this skew causes strange effects when you run sparc32 binary on sparc64 kernel (compared to sparc32 binary on sparc32 kernel) as kernel disagrees with userspace on O_NDELAY definition. https://github.com/libuv/libuv/issues/1830 has more details. I tried to trace the O_NDELAY definition and stopped at linux-2.1.29: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/diff/include/asm-sparc/fcntl.h?id=b7b4d2d2c1809575374269e14d86ee1953bd168c which brought O_NDELAY to O_NONBLOCK but did not make them match exactly. Question time: 1. Why is sparc32 special? Does it have something to do with compatibility to other OSes of that time? (Solaris? BSD?) fs/fcntl.c has kernel handling: /* required for strict SunOS emulation */ if (O_NONBLOCK != O_NDELAY) if (arg & O_NDELAY) arg |= O_NONBLOCK; but why does it leak to to userspace header definition? I think it should not. 2. Should sparc64-glibc change it's definition? Say, from #define O_NDELAY (0x0004 | O_NONBLOCK) to #define O_NDELAY O_NONBLOCK I think it should. 3. Should sparc32-linux (and glibc) change it's definition? Say, from #if defined(__sparc__) && defined(__arch64__) #define O_NDELAY 0x0004 #else #define O_NDELAY (0x0004 | O_NONBLOCK) #endif to #define O_NDELAY (0x0004 | O_NONBLOCK) or even to #define O_NDELAY O_NONBLOCK and make sure kernel maps old O_NDELAY to O_NONBLOCK? I think '#define O_NDELAY O_NONBLOCK' would be most consistent. What do you think? Thanks! -- Sergei