From patchwork Mon Aug 4 15:23:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chun-Yi Lee X-Patchwork-Id: 4670671 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 59AD49F375 for ; Mon, 4 Aug 2014 15:23:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DCD7C2015A for ; Mon, 4 Aug 2014 15:23:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1BF002013A for ; Mon, 4 Aug 2014 15:23:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752690AbaHDPXm (ORCPT ); Mon, 4 Aug 2014 11:23:42 -0400 Received: from mail-wg0-f41.google.com ([74.125.82.41]:40904 "EHLO mail-wg0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751033AbaHDPXl (ORCPT ); Mon, 4 Aug 2014 11:23:41 -0400 Received: by mail-wg0-f41.google.com with SMTP id z12so7861220wgg.0 for ; Mon, 04 Aug 2014 08:23:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=rmyQvEuoSZe60BDQNM15V7gl6sgd/EMzNf4+9T4CRng=; b=o4c7qH/Lstsh0idM30C5ULT99AMnmOT0ocuFpo14WJSw5y8DGkppsG2FODtpzkYvva NeNYc3QBBhLB7eRwe4UIdbcVOujJ/rAY8zViQUs6Aa/ynSnek46PhI1xIwBXE3t7Ia4E zOrCERTQeIkqVGMdqPPHtFvz/So5bJrU9Ds0JBDI+ecrEK9ueIqB6oxEa8ynvx9vjKbh 3wCT+dvAwPDHNhoY2krxYY6uYNNdn0GALDVCUYKM0V4XfZD8V8Zsh7aF0CyA6rwZzWZo r2c8y40VXRK+Fhho2PQGNK2sMbq+V2SXtuWX3pgb+o443mNkinWraArO5h6LKISDeg81 OpaQ== X-Received: by 10.194.222.197 with SMTP id qo5mr33613243wjc.78.1407165818582; Mon, 04 Aug 2014 08:23:38 -0700 (PDT) Received: from linux-rxt1.site ([124.11.22.254]) by mx.google.com with ESMTPSA id x11sm44249917wjr.15.2014.08.04.08.23.34 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Aug 2014 08:23:37 -0700 (PDT) From: "Lee, Chun-Yi" X-Google-Original-From: "Lee, Chun-Yi" To: "Rafael J. Wysocki" , Len Brown , Pavel Machek Cc: Takashi Iwai , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, "Lee, Chun-Yi" Subject: [PATCH v2] Hibernate: check unsafe page should not in e820 reserved region Date: Mon, 4 Aug 2014 23:23:21 +0800 Message-Id: <1407165801-24648-1-git-send-email-jlee@suse.com> X-Mailer: git-send-email 1.8.4.5 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When the machine doesn't well handle the e820 persistent when hibernate resuming, then it may causes page fault when writing image to snapshot buffer: [ 17.929495] BUG: unable to handle kernel paging request at ffff880069d4f000 [ 17.933469] IP: [] load_image_lzo+0x810/0xe40 [ 17.933469] PGD 2194067 PUD 77ffff067 PMD 2197067 PTE 0 [ 17.933469] Oops: 0002 [#1] SMP ... The ffff880069d4f000 page is in e820 reserved region of resume boot kernel: [ 0.000000] BIOS-e820: [mem 0x0000000069d4f000-0x0000000069e12fff] reserved ... [ 0.000000] PM: Registered nosave memory: [mem 0x69d4f000-0x69e12fff] So snapshot.c mark the pfn to forbidden pages map. But, this page is also in the memory bitmap in snapshot image because it's an original page used by image kernel, so it will also mark as an unsafe(free) page in prepare_image(). That means the page in e820 when resuming mark as "forbidden" and "free", it causes get_buffer() treat it as an allocated unsafe page. Then snapshot_write_next() return this page to load_image, load_image writing content to this address, but this page didn't really allocated . So, we got page fault. Although the root cause is from BIOS, I think aggressive check and significant message in kernel will better then a page fault for issue tracking, especially when serial console unavailable. This patch adds code in mark_unsafe_pages() for check does free pages in nosave region. If so, then it print message and return fault to stop whole S4 resume process: [ 8.166004] PM: Image loading progress: 0% [ 8.658717] PM: 0x6796c000 in e820 nosave region: [mem 0x6796c000-0x6796cfff] [ 8.918737] PM: Read 2511940 kbytes in 1.04 seconds (2415.32 MB/s) [ 8.926633] PM: Error -14 resuming [ 8.933534] PM: Failed to load hibernation image, recovering. v2: + removed empty check of nosave_regions list. + fixed the typo of "region" in code for error message and patch comment. Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Takashi Iwai Acked-by: Pavel Machek Signed-off-by: Lee, Chun-Yi --- kernel/power/snapshot.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 4fc5c32..c4b8093 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -954,6 +954,25 @@ static void mark_nosave_pages(struct memory_bitmap *bm) } } +static bool is_nosave_page(unsigned long pfn) +{ + struct nosave_region *region; + + list_for_each_entry(region, &nosave_regions, list) { + if (pfn >= region->start_pfn && pfn < region->end_pfn) { + pr_err("PM: %#010llx in e820 nosave region: " + "[mem %#010llx-%#010llx]\n", + (unsigned long long) pfn << PAGE_SHIFT, + (unsigned long long) region->start_pfn << PAGE_SHIFT, + ((unsigned long long) region->end_pfn << PAGE_SHIFT) + - 1); + return true; + } + } + + return false; +} + /** * create_basic_memory_bitmaps - create bitmaps needed for marking page * frames that should not be saved and free page frames. The pointers @@ -2015,7 +2034,7 @@ static int mark_unsafe_pages(struct memory_bitmap *bm) do { pfn = memory_bm_next_pfn(bm); if (likely(pfn != BM_END_OF_MAP)) { - if (likely(pfn_valid(pfn))) + if (likely(pfn_valid(pfn)) && !is_nosave_page(pfn)) swsusp_set_page_free(pfn_to_page(pfn)); else return -EFAULT;