From owner-freebsd-x11@FreeBSD.ORG Fri Feb 14 20:38:42 2014 Return-Path: Delivered-To: freebsd-x11@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 98DB7FB3; Fri, 14 Feb 2014 20:38:42 +0000 (UTC) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 15B9F1462; Fri, 14 Feb 2014 20:38:41 +0000 (UTC) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.14.7/8.14.7) with ESMTP id s1EKcV9s069510; Fri, 14 Feb 2014 22:38:31 +0200 (EET) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.8.3 kib.kiev.ua s1EKcV9s069510 Received: (from kostik@localhost) by tom.home (8.14.7/8.14.7/Submit) id s1EKcVp2069509; Fri, 14 Feb 2014 22:38:31 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Fri, 14 Feb 2014 22:38:31 +0200 From: Konstantin Belousov To: Andriy Gapon Subject: Re: [TTM] Unable to allocate page Message-ID: <20140214203831.GV24664@kib.kiev.ua> References: <52FE2063.9090905@FreeBSD.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="S+p9DbwVuimCDe+R" Content-Disposition: inline In-Reply-To: <52FE2063.9090905@FreeBSD.org> User-Agent: Mutt/1.5.22 (2013-10-16) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on tom.home Cc: freebsd-x11@FreeBSD.org, FreeBSD Current X-BeenThere: freebsd-x11@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: X11 on FreeBSD -- maintaining and support List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Feb 2014 20:38:42 -0000 --S+p9DbwVuimCDe+R Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Feb 14, 2014 at 03:55:47PM +0200, Andriy Gapon wrote: >=20 > I am using "radeonkms" on a machine with quite mixed, diverse and varying= loads. > Sometimes I get an X server crash like the following: >=20 > kernel: [TTM] Unable to allocate page > kernel: error: [drm:pid1815:radeon_gem_object_create] *ERROR* Failed to a= llocate > GEM object (25591808, 2, 4096, -12) > kernel: [TTM] Unable to allocate page > kernel: [TTM] Buffer eviction failed > kernel: vm_fault: pager read error, pid 1815 (Xorg) > kernel: pid 1815 (Xorg), uid 0: exited on signal 11 (core dumped) >=20 > At the same time there was the following in X servers stderr: > Failed to allocate : > size : 25589760 bytes > alignment : 256 bytes > domains : 2 >=20 > I wonder if this is a generic problem for example caused by severe resour= ce > exhaustion or if this is something where FreeBSD specific code does not d= o its best. > In particular, it caught my attention that ttm_get_pages() effectively has > semantics of M_NOWAIT as it never retries allocation failures in > vm_page_alloc_contig(). It seems you are right that Linux tries much harder to allocate the page than the current FreeBSD TTM ports does. Can you try the following patch ? I did not tested it, only compiled. Please keep witness enabled. diff --git a/sys/dev/drm2/ttm/ttm_bo.c b/sys/dev/drm2/ttm/ttm_bo.c index d87940c..748c969 100644 --- a/sys/dev/drm2/ttm/ttm_bo.c +++ b/sys/dev/drm2/ttm/ttm_bo.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include =20 #define TTM_ASSERT_LOCKED(param) #define TTM_DEBUG(fmt, arg...) @@ -1489,15 +1490,23 @@ int ttm_bo_global_init(struct drm_global_reference = *ref) container_of(ref, struct ttm_bo_global_ref, ref); struct ttm_bo_global *glob =3D ref->object; int ret; + int tries; =20 sx_init(&glob->device_list_mutex, "ttmdlm"); mtx_init(&glob->lru_lock, "ttmlru", NULL, MTX_DEF); glob->mem_glob =3D bo_ref->mem_glob; + tries =3D 0; +retry: glob->dummy_read_page =3D vm_page_alloc_contig(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ, 1, 0, VM_MAX_ADDRESS, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE); =20 if (unlikely(glob->dummy_read_page =3D=3D NULL)) { + if (tries < 1) { + vm_pageout_grow_cache(tries, 0, VM_MAX_ADDRESS); + tries++; + goto retry; + } ret =3D -ENOMEM; goto out_no_drp; } diff --git a/sys/dev/drm2/ttm/ttm_page_alloc.c b/sys/dev/drm2/ttm/ttm_page_= alloc.c index 3c0f18a..29a3621 100644 --- a/sys/dev/drm2/ttm/ttm_page_alloc.c +++ b/sys/dev/drm2/ttm/ttm_page_alloc.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include =20 #ifdef TTM_HAS_AGP #include @@ -476,6 +477,14 @@ static void ttm_handle_caching_state_failure(struct pg= list *pages, } } =20 +static vm_paddr_t +ttm_alloc_high_bound(int ttm_alloc_flags) +{ + + return ((ttm_alloc_flags & TTM_PAGE_FLAG_DMA32) ? 0xffffffff : + VM_MAX_ADDRESS); +} + /** * Allocate new pages with correct caching. * @@ -491,6 +500,7 @@ static int ttm_alloc_new_pages(struct pglist *pages, in= t ttm_alloc_flags, unsigned i, cpages, aflags; unsigned max_cpages =3D min(count, (unsigned)(PAGE_SIZE/sizeof(vm_page_t))); + int tries; =20 aflags =3D VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_NOOBJ | ((ttm_alloc_flags & TTM_PAGE_FLAG_ZERO_ALLOC) !=3D 0 ? @@ -501,11 +511,18 @@ static int ttm_alloc_new_pages(struct pglist *pages, = int ttm_alloc_flags, M_WAITOK | M_ZERO); =20 for (i =3D 0, cpages =3D 0; i < count; ++i) { + tries =3D 0; +retry: p =3D vm_page_alloc_contig(NULL, 0, aflags, 1, 0, - (ttm_alloc_flags & TTM_PAGE_FLAG_DMA32) ? 0xffffffff : - VM_MAX_ADDRESS, PAGE_SIZE, 0, - ttm_caching_state_to_vm(cstate)); + ttm_alloc_high_bound(ttm_alloc_flags), + PAGE_SIZE, 0, ttm_caching_state_to_vm(cstate)); if (!p) { + if (tries < 3) { + vm_pageout_grow_cache(tries, 0, + ttm_alloc_high_bound(ttm_alloc_flags)); + tries++; + goto retry; + } printf("[TTM] Unable to get page %u\n", i); =20 /* store already allocated pages in the pool after @@ -707,6 +724,7 @@ static int ttm_get_pages(vm_page_t *pages, unsigned npa= ges, int flags, int gfp_flags, aflags; unsigned count; int r; + int tries; =20 aflags =3D VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | ((flags & TTM_PAGE_FLAG_ZERO_ALLOC) !=3D 0 ? VM_ALLOC_ZERO : 0); @@ -714,11 +732,18 @@ static int ttm_get_pages(vm_page_t *pages, unsigned n= pages, int flags, /* No pool for cached pages */ if (pool =3D=3D NULL) { for (r =3D 0; r < npages; ++r) { + tries =3D 0; +retry: p =3D vm_page_alloc_contig(NULL, 0, aflags, 1, 0, - (flags & TTM_PAGE_FLAG_DMA32) ? 0xffffffff : - VM_MAX_ADDRESS, PAGE_SIZE, + ttm_alloc_high_bound(flags), PAGE_SIZE, 0, ttm_caching_state_to_vm(cstate)); if (!p) { + if (tries < 3) { + vm_pageout_grow_cache(tries, 0, + ttm_alloc_high_bound(flags)); + tries++; + goto retry; + } printf("[TTM] Unable to allocate page\n"); return -ENOMEM; } --S+p9DbwVuimCDe+R Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (FreeBSD) iQIcBAEBAgAGBQJS/n7GAAoJEJDCuSvBvK1BCX0P/ijVY9HkXpfzY+N1D2NxMqMQ sybDLy51tbQ0NdAQvTrwOrkTlJEDTjKnOPKsS4Gt61scP10iCQa5csPLhgzITy9r aO44T58ALb0l03gekdmY41g0yCXYa9sR6kLLF0pyJ7yAAhOK0HUs+9oW+41p/LCc Fc5KGB+eHv+bz7mCJlj5LUipMSflhjO9dea02OmYqzWSQF48kYxPb8ZOnjMQpp9S sNedG6iPnLVxqGq8TtZ5YmBjuOkZgYusRS+9CvwJjUqTSATaour5UOQ+Ip70iWWB p789dcvdR4HAzwDlsoU/xIJljn/4OUaaMJaQgphiAmsfB8Iuv9nF/4vMkeFIw5xO /ynzG47fKROttSd2dh78w3T4NylcVLwloBYSBh0FPNnFup2Ib9oatzWM/tWgMQf+ BPLdkSFUnPhuCAQE1CNIMRI2vrgyp8Vi5VexW0V3JstkAC2VtnvTC/bmQ3WjU5aX c1gzyyf5iixQ7ZeOlTc12rGdrgsJfgxwRD3yJpDy6CFprcVyU6nTyfh70usWx1N4 +GMTnY82+cdZKHlAXchjAIWSz0FrnKtlMwXGdoau0WsyiHKSNCWB9kiC3jQHjHhS 9Nohx9ivuFJrDickQUUyQxxF0vH7HnspjtYziUPG/b6PBCYezt1MC6XY/OcD7Bx3 0yXee+dJPv8VEr//3F8u =Jj8E -----END PGP SIGNATURE----- --S+p9DbwVuimCDe+R--