From patchwork Tue Nov 10 16:30:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Ivanov X-Patchwork-Id: 1397737 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cambridgegreys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=KEnSHEIg; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (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 ozlabs.org (Postfix) with ESMTPS id 4CVtdl5shRz9sRK for ; Wed, 11 Nov 2020 03:30:51 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=3rg2xT+m07Db3osNB08yIGbEfQG079qdvmuJFUpWuKw=; b=KEnSHEIgIps5QRc31R3gFGidST PJZxnOGXpXepW4wMaotnmqbvysQEU/AJ3WGg4p6kbJVjlcIsxUSNJcYpUCorikhqLhf/f4UFfR3IQ BCbSi+RrX4hiz8s2WjDZfwY+ddZ4d78rI+sLll6omnUbJwsujLdiDjmkrQsAtG1tTvMUtkj0DoRXf U98cepeKxlVj+VmNio1rHaJfx/o0J4vbd5uLRpxP3RVwx8GnXJqKtvme1huiFx6Q2mmcgyHL7Abgk jKhZy/oKBwqUy3Cu7jMQtC6RXS7V1ExL45cc/vRqgh7n6O4kWeriw1/Uoa4Npi6L6QyacuMUnx9b0 oPqAul4g==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kcWXf-00078a-9R; Tue, 10 Nov 2020 16:30:47 +0000 Received: from ivanoab7.miniserver.com ([37.128.132.42] helo=www.kot-begemot.co.uk) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kcWXd-00077W-1f for linux-um@lists.infradead.org; Tue, 10 Nov 2020 16:30:46 +0000 Received: from tun252.jain.kot-begemot.co.uk ([192.168.18.6] helo=jain.kot-begemot.co.uk) by www.kot-begemot.co.uk with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kcWXZ-0008KT-Eh; Tue, 10 Nov 2020 16:30:41 +0000 Received: from jain.kot-begemot.co.uk ([192.168.3.3]) by jain.kot-begemot.co.uk with esmtp (Exim 4.92) (envelope-from ) id 1kcWXW-0005zS-6c; Tue, 10 Nov 2020 16:30:40 +0000 From: anton.ivanov@cambridgegreys.com To: linux-um@lists.infradead.org Subject: [PATCH] um: allow using glibc string functions instead of generics Date: Tue, 10 Nov 2020 16:30:34 +0000 Message-Id: <20201110163034.22963-1-anton.ivanov@cambridgegreys.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Spam-Score: -1.0 X-Spam-Score: -1.0 X-Clacks-Overhead: GNU Terry Pratchett X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201110_113045_195865_22187BAF X-CRM114-Status: GOOD ( 17.35 ) X-Spam-Score: 0.4 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.4 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard@nod.at, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Anton Ivanov UML kernel runs as a normal userspace process and can use the optimized glibc strings functions like strcpy, memcpy, etc. The support is optional and is turned on/of using a config option. Using glibc functions results in a slightly smaller executable when linked dynamically as well as anything between 1% and 5% performance improvements. Signed-off-by: Anton Ivanov --- arch/um/Kconfig | 11 +++++ arch/um/include/asm/string.h | 72 +++++++++++++++++++++++++++ arch/um/include/shared/os_string.h | 30 ++++++++++++ arch/um/os-Linux/Makefile | 4 +- arch/um/os-Linux/string.c | 78 ++++++++++++++++++++++++++++++ 5 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 arch/um/include/asm/string.h create mode 100644 arch/um/include/shared/os_string.h create mode 100644 arch/um/os-Linux/string.c diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 4b799fad8b48..961cf3af3ff0 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -189,6 +189,17 @@ config UML_TIME_TRAVEL_SUPPORT It is safe to say Y, but you probably don't need this. +config UML_USE_HOST_STRINGS + bool + default y + prompt "Use glibc strings and memory functions" + help + UML runs as a normal userspace process. As a result it can use + the optimized strcpy, memcpy, etc from glibc instead of the + kernel generic equivalents. This provides some minimal speedup + in the 1% or so range for most applications. It also results in + a smaller executable. + endmenu source "arch/um/drivers/Kconfig" diff --git a/arch/um/include/asm/string.h b/arch/um/include/asm/string.h new file mode 100644 index 000000000000..1fba8d59afe5 --- /dev/null +++ b/arch/um/include/asm/string.h @@ -0,0 +1,72 @@ +#ifndef __ASM_UM_STRING_H +#define __ASM_UM_STRING_H + +#ifdef CONFIG_UML_USE_HOST_STRINGS + +/* UML saves and restores registers when going to/from + * userspace. This allows the use of normal userspace + * functions for strings with all relevant glibc processor + * optimizations + */ + +#include + +#define __HAVE_ARCH_STRCPY + +#define strcpy(dest, src) os_strcpy(dest, src); + +#define __HAVE_ARCH_STRNCPY + +#define strncpy(dest, src, count) os_strncpy(dest, src, count) + +#define __HAVE_ARCH_STRCAT + +#define strcat(dest, src) os_strcat(dest, src) + +#define __HAVE_ARCH_STRNCAT + +#define strncat(dest, src, count) os_strncat(dest, src, count) + +#define __HAVE_ARCH_STRCMP + +#define strcmp(cs, ct) os_strcmp(cs, ct) + +#define __HAVE_ARCH_STRNCMP + +#define strncmp(cs, ct, count) os_strncmp(cs, ct, count) + +#define __HAVE_ARCH_STRCHR + +#define strchr(s, c) os_strchr(s, c) + +#define __HAVE_ARCH_STRLEN + +#define strlen(s) os_strlen(s) + +#define __HAVE_ARCH_MEMCPY + +#define memcpy(dst, src, n) os_memcpy(dst, src, n) + +#define __HAVE_ARCH_MEMMOVE + +#define memmove(dest, src, n) os_memmove(dest, src, n) + +#define __HAVE_ARCH_MEMCHR + +#define memchr(cs, c, count) os_memchr(cs, c, count) + +#define __HAVE_ARCH_STRNLEN + +#define strnlen(s, count) os_strnlen(s, count) + +#define __HAVE_ARCH_STRSTR + +#define strstr(cs, ct) os_strstr(cs, ct) + +#define __HAVE_ARCH_MEMSET + +#define memset(dst, c, n) os_memset(dst, c, n) + +#endif + +#endif /* __ASM_GENERIC_STRING_H */ diff --git a/arch/um/include/shared/os_string.h b/arch/um/include/shared/os_string.h new file mode 100644 index 000000000000..b9662f622e77 --- /dev/null +++ b/arch/um/include/shared/os_string.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk}) + * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ + +#ifndef __OS_STRING_H__ +#define __OS_STRING_H__ + +#include + +/* string.c */ + +extern char *os_strcpy(char *dest, const char *src); +extern char *os_strncpy(char *dest, const char *src, size_t count); +extern char *os_strcat(char *dest, const char *src); +extern char *os_strncat(char *dest, const char *src, size_t count); +extern int os_strcmp(const char *cs, const char *ct); +extern int os_strncmp(const char *cs, const char *ct, size_t count); +extern char *os_strchr(const char *s, int c); +extern size_t os_strlen(const char *s); +extern void *os_memcpy(void *dest, const void *src, size_t n); +extern void *os_memmove(void *dest, const void *src, size_t n); +extern void *os_memchr(const void *cs, int c, size_t count); +extern size_t os_strnlen(const char *s, size_t count); +extern char *os_strstr(const char *cs, const char *ct); +extern void *os_memset(void *s, int c, size_t n); + +#endif diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 839915b8c31c..f117f2514191 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -8,12 +8,12 @@ KCOV_INSTRUMENT := n obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o \ - umid.o user_syms.o util.o drivers/ skas/ + umid.o user_syms.o util.o string.o drivers/ skas/ obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o USER_OBJS := $(user-objs-y) elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ - tty.o umid.o util.o + tty.o umid.o util.o string.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/string.c b/arch/um/os-Linux/string.c new file mode 100644 index 000000000000..abc76e2aecb3 --- /dev/null +++ b/arch/um/os-Linux/string.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ + +#include +#include +#include +#include + +inline char *os_strcpy(char *dest, const char *src) +{ + return strcpy(dest, src); +} + +inline char *os_strncpy(char *dest, const char *src, size_t count) +{ + return strncpy(dest, src, count); +} + +inline char *os_strcat(char *dest, const char *src) +{ + return strcat(dest, src); +} +inline char *os_strncat(char *dest, const char *src, size_t count) +{ + return strncat(dest, src, count); +} + +inline int os_strcmp(const char *cs, const char *ct) +{ + return strcmp(cs, ct); +} + +inline int os_strncmp(const char *cs, const char *ct, size_t count) +{ + return strncmp(cs, ct, count); +} + +inline char *os_strchr(const char *s, int c) +{ + return strchr(s, c); +} +inline size_t os_strlen(const char *s) +{ + return strlen(s); +} + +inline void *os_memcpy(void *dest, const void *src, size_t n) +{ + return memcpy(dest, src, n); +} + +inline void *os_memmove(void *dest, const void *src, size_t n) +{ + return memmove(dest, src, n); +} + +inline void *os_memchr(const void *cs, int c, size_t count) +{ + return memchr(cs, c, count); +} + +inline size_t os_strnlen(const char *s, size_t count) +{ + return strnlen(s, count); +} + +inline char *os_strstr(const char *cs, const char *ct) +{ + return strstr(cs, ct); +} + +inline void *os_memset(void *s, int c, size_t n) +{ + return memset(s, c, n); +} +