From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752786AbcFVQ0q (ORCPT ); Wed, 22 Jun 2016 12:26:46 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:3845 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751315AbcFVQ0p (ORCPT ); Wed, 22 Jun 2016 12:26:45 -0400 X-IBM-Helo: d06dlp02.portsmouth.uk.ibm.com X-IBM-MailFrom: gerald.schaefer@de.ibm.com X-IBM-RcptTo: linux-kernel@vger.kernel.org From: Gerald Schaefer To: Andrew Morton , Luiz Capitulino Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Naoya Horiguchi , Mike Kravetz , Hillf Danton , "Kirill A . Shutemov" , Dave Hansen , Paul Gortmaker , "Aneesh Kumar K . V" , Gerald Schaefer , Martin Schwidefsky , Heiko Carstens Subject: [PATCH] mm/hugetlb: clear compound_mapcount when freeing gigantic pages Date: Wed, 22 Jun 2016 18:25:19 +0200 X-Mailer: git-send-email 2.6.6 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16062216-0020-0000-0000-000001C6D026 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062216-0021-0000-0000-00001C7BBAB6 Message-Id: <1466612719-5642-1-git-send-email-gerald.schaefer@de.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-06-22_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606220168 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org While working on s390 support for gigantic hugepages I ran into the following "Bad page state" warning when freeing gigantic pages: BUG: Bad page state in process bash pfn:580001 page:000003d116000040 count:0 mapcount:0 mapping:ffffffff00000000 index:0x0 flags: 0x7fffc0000000000() page dumped because: non-NULL mapping This is because page->compound_mapcount, which is part of a union with page->mapping, is initialized with -1 in prep_compound_gigantic_page(), and not cleared again during destroy_compound_gigantic_page(). Fix this by clearing the compound_mapcount in destroy_compound_gigantic_page() before clearing compound_head. Interestingly enough, the warning will not show up on x86_64, although this should not be architecture specific. Apparently there is an endianness issue, combined with the fact that the union contains both a 64 bit ->mapping pointer and a 32 bit atomic_t ->compound_mapcount as members. The resulting bogus page->mapping on x86_64 therefore contains 00000000ffffffff instead of ffffffff00000000 on s390, which will falsely trigger the PageAnon() check in free_pages_prepare() because page->mapping & PAGE_MAPPING_ANON is true on little-endian architectures like x86_64 in this case (the page is not compound anymore, ->compound_head was already cleared before). As a result, page->mapping will be cleared before doing the checks in free_pages_check(). Not sure if the bogus "PageAnon() returning true" on x86_64 for the first tail page of a gigantic page (at this stage) has other theoretical implications, but they would also be fixed with this patch. Signed-off-by: Gerald Schaefer --- mm/hugetlb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index e197cd7..b64f8b7 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1030,6 +1030,7 @@ static void destroy_compound_gigantic_page(struct page *page, int nr_pages = 1 << order; struct page *p = page + 1; + atomic_set(compound_mapcount_ptr(page), 0); for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { clear_compound_head(p); set_page_refcounted(p); -- 2.6.6