Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Nov 2016 16:55:28 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Sebastian Huber <sebastian.huber@embedded-brains.de>
Cc:        FreeBSD <freebsd-hackers@freebsd.org>
Subject:   Re: Should page allocator zero the pages for UMA?
Message-ID:  <20161108145528.GN54029@kib.kiev.ua>
In-Reply-To: <5821DC2E.9020302@embedded-brains.de>
References:  <5821DC2E.9020302@embedded-brains.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Nov 08, 2016 at 03:07:42PM +0100, Sebastian Huber wrote:
> Hello,
> 
> we use the FreeBSD network, USB and SD/MMC card stacks for the real-time 
> operating system RTEMS:
> 
> https://git.rtems.org/rtems-libbsd
> 
> I update currently from FreeBSD 9.3 to head. We use the UMA from FreeBSD 
> with a custom page allocator:
> 
> https://git.rtems.org/rtems-libbsd/tree/rtemsbsd/rtems/rtems-kernel-page.c
> 
> The FreeBSD 9.3 based port worked well with uninitialized pages, e.g. 
> random or previous content. However, after the update to head I had to 
> zero initialize the pages. One issue was an incomplete
> 
> struct inpcb {
> [...]
>      struct    inpcbport *inp_phd;    /* (i/h) head of this list */
> #define inp_zero_size offsetof(struct inpcb, inp_gencnt)
>      inp_gen_t    inp_gencnt;    /* (c) generation count */
>      struct llentry    *inp_lle;    /* cached L2 information */
>      struct rwlock    inp_lock;
>      rt_gen_t    inp_rt_cookie;    /* generation for route entry */
>      union {                /* cached L3 information */
>          struct route inpu_route;
>          struct route_in6 inpu_route6;
>      } inp_rtu;
> #define inp_route inp_rtu.inpu_route
> #define inp_route6 inp_rtu.inpu_route6
> };
> 
> initialization. The initialization consists of two parts:
> 
> static int
> udp_inpcb_init(void *mem, int size, int flags)
> {
>      struct inpcb *inp;
> 
>      inp = mem;
>      INP_LOCK_INIT(inp, "inp", "udpinp");
>      return (0);
> }
> 
> /*
>   * Allocate a PCB and associate it with the socket.
>   * On success return with the PCB locked.
>   */
> int
> in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
> {
>      struct inpcb *inp;
>      int error;
> 
> #ifdef INVARIANTS
>      if (pcbinfo == &V_tcbinfo) {
>          INP_INFO_RLOCK_ASSERT(pcbinfo);
>      } else {
>          INP_INFO_WLOCK_ASSERT(pcbinfo);
>      }
> #endif
> 
>      error = 0;
>      inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT);
>      if (inp == NULL)
>          return (ENOBUFS);
>      bzero(inp, inp_zero_size);
>      inp->inp_pcbinfo = pcbinfo;
>      inp->inp_socket = so;
>      inp->inp_cred = crhold(so->so_cred);
>      inp->inp_inc.inc_fibnum = so->so_fibnum;
> [...]
> 
> This lets at least inp_route uninitialized leading to a crash during 
> destruction, e.g.
> 
>      if (inp->inp_route.ro_rt) {
>          RTFREE(inp->inp_route.ro_rt);
>          inp->inp_route.ro_rt = (struct rtentry *)NULL;
>      }
> 
> uses uninitialized data.
> 
> Did something in the page allocator change between FreeBSD 9.3 and 
> trunk, so that page are now zero initialized or is this a bug in 
> udp_inpcb_init()?

Nothing guarantees that returned items are zeroed out automatically.
Pages are not returned zeroed by VM page allocator, it might indicate
that the allocated page happens to be zeroed by PG_ZERO flag.  Unless
M_ZERO is passed to uma_zalloc(), item is not zeroed.

I am not sure, you did not demonstrated zone initialization, but it seems
that your zone is having zone init function.  If this is true, than I do not
see why do you consider it possible to have items automatically zeroed at
all.  Uma calls the init function at the bulk allocation time, and constructor
for each item returned by uma_zalloc().  No implicit zeroing occurs there.

If your zone does not have init/fini functions, nor ctors/dtors, then
HEAD and stable/11 actually actively trash items to catch reliance on
the uninitialized memory being zero.  Look for trash_ctor in uma_core.c.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20161108145528.GN54029>