Received: by 10.223.185.116 with SMTP id b49csp288610wrg; Tue, 13 Feb 2018 21:58:57 -0800 (PST) X-Google-Smtp-Source: AH8x225+ml1qpOe2l5fgMQUxo66Wh6isVs1MQb6pcTxxaMYt4jaZi5s44uFpgTcoHK+ugyEAFPg2 X-Received: by 2002:a17:902:6e01:: with SMTP id u1-v6mr3428815plk.12.1518587937791; Tue, 13 Feb 2018 21:58:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518587937; cv=none; d=google.com; s=arc-20160816; b=Oe+bzl0+dvo8OuTWbFz317/9YRgANvi37KlOoaL7Dfy7rnAx1CV6yITE5n5cF4E0DV ZWRNL+hVSmNelSPro/vAGS4DD7EImy/TJYpeGLTU4YybzpLY/vRC+oX8NkD7YM2pw8Rk /1rOZ7kD41ecRoKY31huvXpbdk5q4RPS0GCbAB31BW45A6MVfPE7jldHUTAok/TVWDET rwaSZnHMB02qFevp39cjmALADhJIDdnmoWbplCR4IEBrA0BVcCd/i9rJ5Kvod4w7Ab9v tFu7ZS8Uv4q4oqSSTh4I7DHIVPCkdhwBbIDB5jYD5jdcD1m2LxSGyN2zKbuwel71zmSf buLg== 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:dkim-signature:arc-authentication-results; bh=IefPXCMEqC+EqdA+HWcfU4u3uZBRCxO78VH9zubabgM=; b=Q1MkJ5xtMGqrP5h6bU4lNjUlT/aFKNgYS39o/TgAemFssO2NesuktgJ3JjM1Krr9m0 hqPUNpjmpRBCzsneXqrtyrB3KM1ZOQsyVxGqKrdXZDRYPHz0vPoUFmtEtDq5MBsTzj+M aKIp/VHYFXgxiFNx5o3k46jqTOiZYxwXnFD+pmcUN08L8t8nUP5N3i+2pPn0c3D5Puxg mAZZB9pproOLqKgLyGILOYMCP0y0XIXXTniia8MpiDUYb/fQEWoBxu5nODPZKYYiKi+7 hluIUUX+YcaIc1dgEAqC2dX4BDr8I7kzjUwMJaCCLmlG3JgB3bRGEaAkQMoi3Nc9kC2S Fl+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=QrXn+b+v; 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=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h13si987793pgf.418.2018.02.13.21.58.43; Tue, 13 Feb 2018 21:58:57 -0800 (PST) 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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=QrXn+b+v; 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=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754320AbeBNF6F (ORCPT + 99 others); Wed, 14 Feb 2018 00:58:05 -0500 Received: from mail-pl0-f66.google.com ([209.85.160.66]:45885 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752707AbeBNF6D (ORCPT ); Wed, 14 Feb 2018 00:58:03 -0500 Received: by mail-pl0-f66.google.com with SMTP id p5so7974653plo.12 for ; Tue, 13 Feb 2018 21:58:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IefPXCMEqC+EqdA+HWcfU4u3uZBRCxO78VH9zubabgM=; b=QrXn+b+v7Da2aQrZYBWHoDCJJDDBMOQT46am1dK6KuG2qSkSSE8Y4l8xpbBl6G5nG6 lOK8ClR+j0/ij1ct76jSJopXJaTlCOaFbVo9yUygMh9gJnqHI/BYNqKWg0a6hvbAHYT7 EQJFXXlVdhH5fR4mPerCTIRlohcQ0e+L68QhchnYUxrCBYXgGIEs6AX+AVoBanErUI1J 6zUyHF87rZnB23NMGA+pgYbJW7Q+fv8eHI3tsdpdXbgR5uQrCOg50ig+OYiNUBDX7rTo ZH0vf54PD+Z/FdCkBu1CddLyEl9rExD+4Xq/dzqTx4NxorFmAZXaKX/aad1g690GLb3n /4Ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IefPXCMEqC+EqdA+HWcfU4u3uZBRCxO78VH9zubabgM=; b=XmWyn8Wo2k3/uGBPbdiNrSRqJqIdeeaLIByR4dM4vIhraOGdZ4HTCHw1S1Js+s/hf3 JgrVQgHKPcKL+T4zmEsa4zMbbfEpFmfatplsJjvIGw14vx6VJliTAbGQWr0O5Heh50xz 4aioqP3LDcdBTda6+agwJcH6Af1pWUlbLg9AspN/FlwtcADpaDXZDAo4u5L6C/dWfIIp w/mj9foqRiFrrV642wSTvQAD5LwDvY1oqTT6p8t6FCyeSyp7e5YyOQ9WPG+2scl6lB4B xmwQ6G6Oni7R6WOAU8OqJFeVAn8kuJRY9LzguLcosd4Rc4HQRkUUp4V2bBIq5TnZm16G 3isA== X-Gm-Message-State: APf1xPBygttYsRh61WzaFodFKaEXq/jBk/xTAZ/Wr1NPBn5OYzZluhoT gTzN44dYky+5FlQC2kxW4Rw= X-Received: by 2002:a17:902:b787:: with SMTP id e7-v6mr3452829pls.317.1518587883449; Tue, 13 Feb 2018 21:58:03 -0800 (PST) Received: from localhost.localdomain ([110.70.52.190]) by smtp.gmail.com with ESMTPSA id 186sm31207578pfe.2.2018.02.13.21.57.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Feb 2018 21:58:02 -0800 (PST) From: Sergey Senozhatsky X-Google-Original-From: Sergey Senozhatsky To: Minchan Kim , Andrew Morton Cc: Mike Rapoport , linux-kernel@vger.kernel.org, linux-mm@kvack.org, Sergey Senozhatsky , Sergey Senozhatsky Subject: [PATCHv3 1/2] zsmalloc: introduce zs_huge_object() function Date: Wed, 14 Feb 2018 14:57:47 +0900 Message-Id: <20180214055747.8420-1-sergey.senozhatsky@gmail.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180210082321.17798-1-sergey.senozhatsky@gmail.com> References: <20180210082321.17798-1-sergey.senozhatsky@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Not every object can be share its zspage with other objects, e.g. when the object is as big as zspage or nearly as big a zspage. For such objects zsmalloc has a so called huge class - every object which belongs to huge class consumes the entire zspage (which consists of a physical page). On x86_64, PAGE_SHIFT 12 box, the first non-huge class size is 3264, so starting down from size 3264, objects can share page(-s) and thus minimize memory wastage. ZRAM, however, has its own statically defined watermark for huge objects - "3 * PAGE_SIZE / 4 = 3072", and forcibly stores every object larger than this watermark (3072) as a PAGE_SIZE object, in other words, to a huge class, while zsmalloc can keep some of those objects in non-huge classes. This results in increased memory consumption. zsmalloc knows better if the object is huge or not. Introduce zs_huge_object() function which tells if the given object can be stored in one of non-huge classes or not. This will let us to drop ZRAM's huge object watermark and fully rely on zsmalloc when we decide if the object is huge. Signed-off-by: Sergey Senozhatsky --- include/linux/zsmalloc.h | 2 ++ mm/zsmalloc.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h index 57a8e98f2708..9a1baf673cc1 100644 --- a/include/linux/zsmalloc.h +++ b/include/linux/zsmalloc.h @@ -47,6 +47,8 @@ void zs_destroy_pool(struct zs_pool *pool); unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t flags); void zs_free(struct zs_pool *pool, unsigned long obj); +bool zs_huge_object(size_t sz); + void *zs_map_object(struct zs_pool *pool, unsigned long handle, enum zs_mapmode mm); void zs_unmap_object(struct zs_pool *pool, unsigned long handle); diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index c3013505c305..e43fc6ebb8e1 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -192,6 +192,7 @@ static struct vfsmount *zsmalloc_mnt; * (see: fix_fullness_group()) */ static const int fullness_threshold_frac = 4; +static size_t zs_huge_class_size; struct size_class { spinlock_t lock; @@ -1417,6 +1418,28 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle) } EXPORT_SYMBOL_GPL(zs_unmap_object); +/** + * zs_huge_object() - Test if a compressed object's size is too big for normal + * zspool classes and it should be stored in a huge class. + * @sz: Size of the compressed object (in bytes). + * + * The function checks if the object's size falls into huge_class + * area. We must take handle size into account and test the actual + * size we are going to use, because zs_malloc() unconditionally + * adds %ZS_HANDLE_SIZE before it performs &size_class lookup. + * + * Context: Any context. + * + * Return: + * * true - The object is too big, it will be stored in the huge class. + * * false - The object will be stored in a normal zspool class. + */ +bool zs_huge_object(size_t sz) +{ + return sz + ZS_HANDLE_SIZE >= zs_huge_class_size; +} +EXPORT_SYMBOL_GPL(zs_huge_object); + static unsigned long obj_malloc(struct size_class *class, struct zspage *zspage, unsigned long handle) { @@ -2404,6 +2427,9 @@ struct zs_pool *zs_create_pool(const char *name) INIT_LIST_HEAD(&class->fullness_list[fullness]); prev_class = class; + if (pages_per_zspage == 1 && objs_per_zspage == 1 + && !zs_huge_class_size) + zs_huge_class_size = size; } /* debug only, don't abort if it fails */ -- 2.16.1