lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210223174540.5526d843@thinkpad>
Date:   Tue, 23 Feb 2021 17:45:40 +0100
From:   Gerald Schaefer <gerald.schaefer@...ux.ibm.com>
To:     Mike Kravetz <mike.kravetz@...cle.com>
Cc:     Andrew Morton <akpm@...ux-foundation.org>, linux-mm@...ck.org,
        linux-kernel@...r.kernel.org, Michal Hocko <mhocko@...e.com>,
        Heiko Carstens <hca@...ux.ibm.com>,
        Sven Schnelle <svens@...ux.ibm.com>
Subject: Re: [RFC] linux-next panic in hugepage_subpool_put_pages()

On Tue, 23 Feb 2021 15:57:40 +0100
Gerald Schaefer <gerald.schaefer@...ux.ibm.com> wrote:

[...]
> What I do not understand is how __free_huge_page() would be called at all
> in the call trace below (set_max_huge_pages -> alloc_pool_huge_page ->
> __free_huge_page -> hugepage_subpool_put_pages). From the code it seems
> that this should not be possible, so I must be missing something.

Ok, looking more closely at the dump and code, I see that __free_huge_page()
was called via alloc_pool_huge_page -> put_page() -> destroy_compound_page()
-> compound_page_dtors[2].

It doesn't feel right that alloc_pool_huge_page() ends up freeing the
newly allocated page again. Maybe some refcounting race, so that put_page()
wrongly assumes it was the last reference?

Also from the dump, I could reconstruct the (head) struct page pointer
that __free_huge_page() was called with. Here is the content of the
head and the first tail page, maybe it can help. page->private in the tail
page was zeroed already in __free_huge_page(), but its original value was
the broken *spool pointer 0000004e00000000, as seen in the register output
of the backtrace.

crash> struct -x page 0000037203dec000
struct page {
  flags = 0x3ffff00000010000, 
  {
    {
      lru = {
        next = 0x37203dec008, 
        prev = 0x37203dec008
      }, 
      mapping = 0x0, 
      index = 0x0, 
      private = 0x0
    }, 
    {
      dma_addr = 0x37203dec008
    }, 
    {
      {
        slab_list = {
          next = 0x37203dec008, 
          prev = 0x37203dec008
        }, 
        {
          next = 0x37203dec008, 
          pages = 0x372, 
          pobjects = 0x3dec008
        }
      }, 
      slab_cache = 0x0, 
      freelist = 0x0, 
      {
        s_mem = 0x0, 
        counters = 0x0, 
        {
          inuse = 0x0, 
          objects = 0x0, 
          frozen = 0x0
        }
      }
    }, 
    {
      compound_head = 0x37203dec008, 
      compound_dtor = 0x0, 
      compound_order = 0x0, 
      compound_mapcount = {
        counter = 0x3dec008
      }, 
      compound_nr = 0x0
    }, 
    {
      _compound_pad_1 = 0x37203dec008, 
      hpage_pinned_refcount = {
        counter = 0x372
      }, 
      deferred_list = {
        next = 0x0, 
        prev = 0x0
      }
    }, 
    {
      _pt_pad_1 = 0x37203dec008, 
      pmd_huge_pte = 0x37203dec008, 
      _pt_pad_2 = 0x0, 
      {
        pt_mm = 0x0, 
        pt_frag_refcount = {
          counter = 0x0
        }
      }, 
      ptl = {
        {
          rlock = {
            raw_lock = {
              lock = 0x0
            }
          }
        }
      }
    }, 
    {
      pgmap = 0x37203dec008, 
      zone_device_data = 0x37203dec008
    }, 
    callback_head = {
      next = 0x37203dec008, 
      func = 0x37203dec008
    }
  }, 
  {
    _mapcount = {
      counter = 0xffffffff
    }, 
    page_type = 0xffffffff, 
    active = 0xffffffff, 
    units = 0xffffffff
  }, 
  _refcount = {
    counter = 0x0
  }, 
  memcg_data = 0x0
}


crash> struct -x page 0000037203dec040
struct page {
  flags = 0x3ffff00000000000, 
  {
    {
      lru = {
        next = 0x37203dec001, 
        prev = 0x2080372ffffffff
      }, 
      mapping = 0x10000000400, 
      index = 0x2, 
      private = 0x0
    }, 
    {
      dma_addr = 0x37203dec001
    }, 
    {
      {
        slab_list = {
          next = 0x37203dec001, 
          prev = 0x2080372ffffffff
        }, 
        {
          next = 0x37203dec001, 
          pages = 0x2080372, 
          pobjects = 0xffffffff
        }
      }, 
      slab_cache = 0x10000000400, 
      freelist = 0x2, 
      {
        s_mem = 0x0, 
        counters = 0x0, 
        {
          inuse = 0x0, 
          objects = 0x0, 
          frozen = 0x0
        }
      }
    }, 
    {
      compound_head = 0x37203dec001, 
      compound_dtor = 0x2, 
      compound_order = 0x8, 
      compound_mapcount = {
        counter = 0xffffffff
      }, 
      compound_nr = 0x100
    }, 
    {
      _compound_pad_1 = 0x37203dec001, 
      hpage_pinned_refcount = {
        counter = 0x2080372
      }, 
      deferred_list = {
        next = 0x10000000400, 
        prev = 0x2
      }
    }, 
    {
      _pt_pad_1 = 0x37203dec001, 
      pmd_huge_pte = 0x2080372ffffffff, 
      _pt_pad_2 = 0x10000000400, 
      {
        pt_mm = 0x2, 
        pt_frag_refcount = {
          counter = 0x0
        }
      }, 
      ptl = {
        {
          rlock = {
            raw_lock = {
              lock = 0x0
            }
          }
        }
      }
    }, 
    {
      pgmap = 0x37203dec001, 
      zone_device_data = 0x2080372ffffffff
    }, 
    callback_head = {
      next = 0x37203dec001, 
      func = 0x2080372ffffffff
    }
  }, 
  {
    _mapcount = {
      counter = 0xffffffff
    }, 
    page_type = 0xffffffff, 
    active = 0xffffffff, 
    units = 0xffffffff
  }, 
  _refcount = {
    counter = 0x0
  }, 
  memcg_data = 0x0
}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ