Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp1286408imm; Wed, 20 Jun 2018 15:10:38 -0700 (PDT) X-Google-Smtp-Source: ADUXVKI0jwi1NsxV9GD1l8MJPJvQKXzZwFlr8z6lBYracVaN2vzftMKAqye+kzaX2k9q5OWXEfB7 X-Received: by 2002:a62:d74d:: with SMTP id v13-v6mr24835757pfl.0.1529532638923; Wed, 20 Jun 2018 15:10:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529532638; cv=none; d=google.com; s=arc-20160816; b=kSbxgPDJTgzMajCMm6LmuVKxenfLruwyRgkZkeWBmYjGYOn8J7lanyrIoizVGIIeir BWSkajn14ufPstypXAwYPHcHh3IZqywdzHJu9mOxMi+6YK9zW8+T7Vp4HmmErSeRLwi6 Y6vE8j5mJR/CtqQ7lJ73hpIJ55nR7BS/DjgOjiqUuK7HWj1ZL8Kr34CuVE/BVU/3zH16 mYtV4GIsYDe3jcOyVFp0k0HqF9cQAlTduMjFibSkoJeR/6q71BXnrJblfkdLVlvP/wWd vm/SK9U866+RJzcS5XcSpBxAfHJcmHJn1+niw9uOjo6YKoAJtBlzyft2tC1Z+TrzCE62 XmtA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=MmVLSq6exIXftJBXRpc0Etl9d7TPtdb4DMy6kKODyi4=; b=RNCQyf+k0JHdgaCdoizmYQ9p0VNxMzxpT1FCwKeIQK8yERUsMsBTsNh1DsjyRyJYaR QWbzhLPjNuSJGkVm4LcTBvS2gQvH8wLhuQDkewoAk2ojiF8L6F6lDDgAkcJL8+xU6v3x 1X+Eo1RitYR8vKLHgor8mqZ7NSQX/hVtVHhyIAD5LSwHoaXBHOFkZW8DflarZG0Z3qUw L8NHyCmEYdjktdag8m0kk+a+qnIZ6wX6Cz8PA5Jdg5WU4JzbYqXSqYPNvdm437Ou64dQ wuNR6YPrBI+HZTiUEkjGm+7FNp9KitdWFNsGhFY3kb5f4WsTZ6jy4UksuqQaS/JaNtLu V15g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c13-v6si2674053pgq.316.2018.06.20.15.10.25; Wed, 20 Jun 2018 15:10:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933674AbeFTWJl (ORCPT + 99 others); Wed, 20 Jun 2018 18:09:41 -0400 Received: from mga01.intel.com ([192.55.52.88]:19370 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933642AbeFTWJe (ORCPT ); Wed, 20 Jun 2018 18:09:34 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Jun 2018 15:09:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,249,1526367600"; d="scan'208";a="66312721" Received: from linksys13920.jf.intel.com (HELO rpedgeco-HP-Z240-Tower-Workstation.jf.intel.com) ([10.7.197.56]) by orsmga001.jf.intel.com with ESMTP; 20 Jun 2018 15:09:33 -0700 From: Rick Edgecombe To: tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, x86@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, kernel-hardening@lists.openwall.com Cc: kristen.c.accardi@intel.com, dave.hansen@intel.com, arjan.van.de.ven@intel.com, Rick Edgecombe Subject: [PATCH 3/3] vmalloc: Add debugfs modfraginfo Date: Wed, 20 Jun 2018 15:09:30 -0700 Message-Id: <1529532570-21765-4-git-send-email-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1529532570-21765-1-git-send-email-rick.p.edgecombe@intel.com> References: <1529532570-21765-1-git-send-email-rick.p.edgecombe@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add debugfs file "modfraginfo" for providing info on module space fragmentation. This can be used for determining if loadable module randomization is causing any problems for extreme module loading situations, like huge numbers of modules or extremely large modules. Sample output when RANDOMIZE_BASE and X86_64 is configured: Largest free space: 847253504 External Memory Fragementation: 20% Allocations in backup area: 0 Sample output otherwise: Largest free space: 847253504 External Memory Fragementation: 20% Signed-off-by: Rick Edgecombe --- mm/vmalloc.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 9e0820c9..afb8fe9 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include +#include #include #include @@ -2785,7 +2787,113 @@ static int __init proc_vmalloc_init(void) proc_create_seq("vmallocinfo", 0400, NULL, &vmalloc_op); return 0; } -module_init(proc_vmalloc_init); +#else +static int proc_vmalloc_init(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_DEBUG_FS +#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_X86_64) +static void print_backup_area(struct seq_file *m, unsigned long backup_cnt) +{ + if (kaslr_enabled()) + seq_printf(m, "Allocations in backup area:\t%lu\n", backup_cnt); +} +static unsigned long get_backup_start(void) +{ + return MODULES_VADDR + MODULES_RAND_LEN; +} +#else +static void print_backup_area(struct seq_file *m, unsigned long backup_cnt) +{ +} +static unsigned long get_backup_start(void) +{ + return 0; +} +#endif + +static int modulefraginfo_debug_show(struct seq_file *m, void *v) +{ + struct list_head *i; + unsigned long last_end = MODULES_VADDR; + unsigned long total_free = 0; + unsigned long largest_free = 0; + unsigned long backup_cnt = 0; + unsigned long gap; + + spin_lock(&vmap_area_lock); + + list_for_each(i, &vmap_area_list) { + struct vmap_area *obj = list_entry(i, struct vmap_area, list); + + if (!(obj->flags & VM_LAZY_FREE) + && obj->va_start >= MODULES_VADDR + && obj->va_end <= MODULES_END) { + + if (obj->va_start >= get_backup_start()) + backup_cnt++; + + gap = (obj->va_start - last_end); + if (gap > largest_free) + largest_free = gap; + total_free += gap; + + last_end = obj->va_end; + } + } + + gap = (MODULES_END - last_end); + if (gap > largest_free) + largest_free = gap; + total_free += gap; + + spin_unlock(&vmap_area_lock); + + seq_printf(m, "Largest free space:\t\t%lu\n", largest_free); + if (total_free) + seq_printf(m, "External Memory Fragementation:\t%lu%%\n", + 100-(100*largest_free/total_free)); + else + seq_puts(m, "External Memory Fragementation:\t0%%\n"); + + print_backup_area(m, backup_cnt); + + return 0; +} + +static int proc_module_frag_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, modulefraginfo_debug_show, NULL); +} + +static const struct file_operations debug_module_frag_operations = { + .open = proc_module_frag_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +static void debug_modfrag_init(void) +{ + debugfs_create_file("modfraginfo", 0x0400, NULL, NULL, + &debug_module_frag_operations); +} +#else +static void debug_modfrag_init(void) +{ +} #endif +#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_PROC_FS) +static int __init info_vmalloc_init(void) +{ + proc_vmalloc_init(); + debug_modfrag_init(); + return 0; +} + +module_init(info_vmalloc_init); +#endif -- 2.7.4