Received: by 10.223.164.221 with SMTP id h29csp2580636wrb; Mon, 30 Oct 2017 06:23:45 -0700 (PDT) X-Google-Smtp-Source: ABhQp+QyqhUd+6Ykbz0eXeWBWH1A+ZkpXwGD9EOQ0fSlH7jWpEB8J2vmeL9bsxolv0R4DZ3PdG7v X-Received: by 10.99.111.6 with SMTP id k6mr7900795pgc.308.1509369825262; Mon, 30 Oct 2017 06:23:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509369825; cv=none; d=google.com; s=arc-20160816; b=dz0iLLSs/CLozCZABmzTxMQJxT2thzMDYJp9g/PM9JebWko9fP6LX2oCaeY7/fLXlT C5tYYrRHn19Fhc9kNHc7nKxyekzHAf+eu3XoSH/2NdVoJlOV37C2sMH4+M1QnZ9mU++z eJfqNu7Mr7xtLovPGhH0fjwgHjqgagbHBsDqgWjPydV6MZrOleK0qAlEmAWG7vAdGH7s 6TIeGaJ9jWkRYYjUNiSkhCpP+GI+c++nFN2RSmzbHUbsfr/soOQVY7XTb7xfb97HEoIg 9Z+C08puua/hCI3Jqc8H7OQdMIdIHqOsonQqtYJCPo9EMY02zKQrubmsN1WAv6Ue9Qb1 7a/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=inbYPeFP5kw+Low9cOpIFxcFbyrEGXMl6yqkBvrf2mE=; b=zp4K/2N6dneNlOXo04tl6MQwpRa0nhYoX8JKj9y9+RihG9MkoZFHHky2gH2iv9n6OD LOEoEA5+cXPV4hb3mHJkGDU1g+JJ5QOoIOntB1ZzbpVjJvDbA48CII8pYIv87/7bIWga 45v/lLRGew4W1q1waMY54eKZ4U9UtGpxRPdQQNkzgiVOqy/lqJ622xjGDAt1oO/dlwYR z9ha2E1Nef0G1TQtKtdr5oXaip2CvHX2KOyyjMtqkiONjNmkuexYtUTRnAt1IW2cjtSn NYuGOdyEoGKopgCIVIv9GTcBKlXAeYjldjfX51j3VaaYm0feYcKwnFYxrKRmd4xkE4Ro GOgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hVp3fcbn; 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=NONE 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 h1si9168535pld.533.2017.10.30.06.23.31; Mon, 30 Oct 2017 06:23:45 -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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hVp3fcbn; 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=NONE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752117AbdJ3NWq (ORCPT + 99 others); Mon, 30 Oct 2017 09:22:46 -0400 Received: from mail-io0-f193.google.com ([209.85.223.193]:45256 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751663AbdJ3NWp (ORCPT ); Mon, 30 Oct 2017 09:22:45 -0400 Received: by mail-io0-f193.google.com with SMTP id i38so27055549iod.2 for ; Mon, 30 Oct 2017 06:22:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=inbYPeFP5kw+Low9cOpIFxcFbyrEGXMl6yqkBvrf2mE=; b=hVp3fcbne6eaGiB7T00zXdBqzSP4zaq3O4xtjSYNzRiZwTFAHlgUzTbpKA3QbAfCnD 5LDcWCukTTOu6GUxAQP76KUYee54LEtV9yMC5AQPFi/S11/4AWRdG1/hH/5ikf2k0SH6 Vo6N+Rz++2pT00A7cWLuaCfASOxVyBANQMAXXEdN9sJ7pPx3EcrgqM/i1uiV103aPXJ9 IailB2OgkoFn2Ec2e37sygMcp6G15KZVfU1C31YvVnan0NtGMWdZUlp9Od/GEkFsF/0o OnQPJHcogJGNeli3qbNfCy4WfhaVF/s2WuZb95R3b370TWdhk+CcOrKdi3Z6+S5NxpU0 MNnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=inbYPeFP5kw+Low9cOpIFxcFbyrEGXMl6yqkBvrf2mE=; b=VwdkITxBoOhJ/QcuQaiAh6JJ002689F94uKunACz/bAyyB1uVT3K1i/uoo9GQPBEs6 Fxg2fbueoljzVkR0hxKfOa4ePdZsp37MV5uBmBbvLUv2pSnfA8Yvs6dtAfJoAlkMYHga NBZ03LzyLjP93nzNWpX7B1JCnScHSgr5EVb6x0IISWqLstnrnCa1Jfr03452L2H9COP4 0IVbIgRWFer1Ttj4BGail1eMnZazTYqq8a2NJN7PrXDKcH+IaxkpKRD0NIUE5RE+4uYB mDgPFJwhFUCSWnhzgKMSHl+wDCxRBpPO1hOSh/4axdNBZK5rCvIFmQVSRWjDJPMcd0wo bB8w== X-Gm-Message-State: AMCzsaW6WvBoK2mFxEEc4kGs77ielSvcLzewL5kYEvA3GYvf/3UoHc4L vVOhDNUJ9Xskt+adkTjCX5xPbx8PfMaSRmAvY3A= X-Received: by 10.36.124.72 with SMTP id a69mr6084183itd.135.1509369764459; Mon, 30 Oct 2017 06:22:44 -0700 (PDT) MIME-Version: 1.0 Received: by 10.2.165.141 with HTTP; Mon, 30 Oct 2017 06:22:04 -0700 (PDT) In-Reply-To: <1509364987-29608-1-git-send-email-kyeongdon.kim@lge.com> References: <1509364987-29608-1-git-send-email-kyeongdon.kim@lge.com> From: Timofey Titovets Date: Mon, 30 Oct 2017 16:22:04 +0300 Message-ID: Subject: Re: [PATCH] ksm : use checksum and memcmp for rb_tree To: Kyeongdon Kim Cc: Andrew Morton , Andrea Arcangeli , Minchan Kim , broonie@kernel.org, mhocko@suse.com, mingo@kernel.org, jglisse@redhat.com, Arvind Yadav , imbrenda@linux.vnet.ibm.com, kirill.shutemov@linux.intel.com, bongkyu.kim@lge.com, linux-mm@kvack.org, Linux Kernel Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2017-10-30 15:03 GMT+03:00 Kyeongdon Kim : > The current ksm is using memcmp to insert and search 'rb_tree'. > It does cause very expensive computation cost. > In order to reduce the time of this operation, > we have added a checksum to traverse before memcmp operation. > > Nearly all 'rb_node' in stable_tree_insert() function > can be inserted as a checksum, most of it is possible > in unstable_tree_search_insert() function. > In stable_tree_search() function, the checksum may be an additional. > But, checksum check duration is extremely small. > Considering the time of the whole cmp_and_merge_page() function, > it requires very little cost on average. > > Using this patch, we compared the time of ksm_do_scan() function > by adding kernel trace at the start-end position of operation. > (ARM 32bit target android device, > over 1000 sample time gap stamps average) > > On original KSM scan avg duration = 0.0166893 sec > 24991.975619 : ksm_do_scan_start: START: ksm_do_scan > 24991.990975 : ksm_do_scan_end: END: ksm_do_scan > 24992.008989 : ksm_do_scan_start: START: ksm_do_scan > 24992.016839 : ksm_do_scan_end: END: ksm_do_scan > ... > > On patch KSM scan avg duration = 0.0041157 sec > 41081.461312 : ksm_do_scan_start: START: ksm_do_scan > 41081.466364 : ksm_do_scan_end: END: ksm_do_scan > 41081.484767 : ksm_do_scan_start: START: ksm_do_scan > 41081.487951 : ksm_do_scan_end: END: ksm_do_scan > ... > > We have tested randomly so many times for the stability > and couldn't see any abnormal issue until now. > Also, we found out this patch can make some good advantage > for the power consumption than KSM default enable. > > Signed-off-by: Kyeongdon Kim > --- > mm/ksm.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 45 insertions(+), 4 deletions(-) > > diff --git a/mm/ksm.c b/mm/ksm.c > index be8f457..66ab4f4 100644 > --- a/mm/ksm.c > +++ b/mm/ksm.c > @@ -150,6 +150,7 @@ struct stable_node { > struct hlist_head hlist; > union { > unsigned long kpfn; > + u32 oldchecksum; > unsigned long chain_prune_time; > }; > /* May be just checksum? i.e. that's can be "old", where checksum can change, in stable tree, checksum also stable. Also, as checksum are stable, may be that make a sense to move it out of union? (I'm afraid of clashes) Also, you miss update comment above struct stable_node, about checksum var. > @@ -1522,7 +1523,7 @@ static __always_inline struct page *chain(struct stable_node **s_n_d, > * This function returns the stable tree node of identical content if found, > * NULL otherwise. > */ > -static struct page *stable_tree_search(struct page *page) > +static struct page *stable_tree_search(struct page *page, u32 checksum) > { > int nid; > struct rb_root *root; > @@ -1540,6 +1541,8 @@ static struct page *stable_tree_search(struct page *page) > > nid = get_kpfn_nid(page_to_pfn(page)); > root = root_stable_tree + nid; > + if (!checksum) > + return NULL; That's not a pointer, and 0x0 - is a valid checksum. Also, jhash2 not so collision free, i.e.: jhash2((uint32_t *) &num, 2, 17); Example of collisions, where hash = 0x0: hash: 0x0 - num: 610041898 hash: 0x0 - num: 4893164379 hash: 0x0 - num: 16423540221 hash: 0x0 - num: 29036382188 You also compare values, so hash = 0, is a acceptable checksum. > again: > new = &root->rb_node; > parent = NULL; > @@ -1550,6 +1553,18 @@ static struct page *stable_tree_search(struct page *page) > > cond_resched(); > stable_node = rb_entry(*new, struct stable_node, node); > + > + /* first make rb_tree by checksum */ > + if (checksum < stable_node->oldchecksum) { > + parent = *new; > + new = &parent->rb_left; > + continue; > + } else if (checksum > stable_node->oldchecksum) { > + parent = *new; > + new = &parent->rb_right; > + continue; > + } > + > stable_node_any = NULL; > tree_page = chain_prune(&stable_node_dup, &stable_node, root); > /* > @@ -1768,7 +1783,7 @@ static struct page *stable_tree_search(struct page *page) > * This function returns the stable tree node just allocated on success, > * NULL otherwise. > */ > -static struct stable_node *stable_tree_insert(struct page *kpage) > +static struct stable_node *stable_tree_insert(struct page *kpage, u32 checksum) > { > int nid; > unsigned long kpfn; > @@ -1792,6 +1807,18 @@ static struct stable_node *stable_tree_insert(struct page *kpage) > cond_resched(); > stable_node = rb_entry(*new, struct stable_node, node); > stable_node_any = NULL; > + > + /* first make rb_tree by checksum */ > + if (checksum < stable_node->oldchecksum) { > + parent = *new; > + new = &parent->rb_left; > + continue; > + } else if (checksum > stable_node->oldchecksum) { > + parent = *new; > + new = &parent->rb_right; > + continue; > + } > + > tree_page = chain(&stable_node_dup, stable_node, root); > if (!stable_node_dup) { > /* > @@ -1850,6 +1877,7 @@ static struct stable_node *stable_tree_insert(struct page *kpage) > > INIT_HLIST_HEAD(&stable_node_dup->hlist); > stable_node_dup->kpfn = kpfn; > + stable_node_dup->oldchecksum = checksum; > set_page_stable_node(kpage, stable_node_dup); > stable_node_dup->rmap_hlist_len = 0; > DO_NUMA(stable_node_dup->nid = nid); > @@ -1907,6 +1935,19 @@ struct rmap_item *unstable_tree_search_insert(struct rmap_item *rmap_item, > > cond_resched(); > tree_rmap_item = rb_entry(*new, struct rmap_item, node); > + > + /* first make rb_tree by checksum */ > + if (rmap_item->oldchecksum < tree_rmap_item->oldchecksum) { > + parent = *new; > + new = &parent->rb_left; > + continue; > + } else if (rmap_item->oldchecksum > + > tree_rmap_item->oldchecksum) { > + parent = *new; > + new = &parent->rb_right; > + continue; > + } > + > tree_page = get_mergeable_page(tree_rmap_item); > if (!tree_page) > return NULL; > @@ -2031,7 +2072,7 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item) > } > > /* We first start with searching the page inside the stable tree */ > - kpage = stable_tree_search(page); > + kpage = stable_tree_search(page, rmap_item->oldchecksum); > if (kpage == page && rmap_item->head == stable_node) { > put_page(kpage); > return; > @@ -2098,7 +2139,7 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item) > * node in the stable tree and add both rmap_items. > */ > lock_page(kpage); > - stable_node = stable_tree_insert(kpage); > + stable_node = stable_tree_insert(kpage, checksum); > if (stable_node) { > stable_tree_append(tree_rmap_item, stable_node, > false); > -- > 2.6.2 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: email@kvack.org Thanks, anyway in general idea looks good. Reviewed-by: Timofey Titovets -- Have a nice day, Timofey. From 1582684052372565644@xxx Mon Oct 30 12:05:31 +0000 2017 X-GM-THRID: 1582684052372565644 X-Gmail-Labels: Inbox,Category Forums