Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Feb 2014 22:38:31 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Andriy Gapon <avg@FreeBSD.org>
Cc:        freebsd-x11@FreeBSD.org, FreeBSD Current <freebsd-current@FreeBSD.org>
Subject:   Re: [TTM] Unable to allocate page
Message-ID:  <20140214203831.GV24664@kib.kiev.ua>
In-Reply-To: <52FE2063.9090905@FreeBSD.org>
References:  <52FE2063.9090905@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--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 <dev/drm2/ttm/ttm_module.h>
 #include <dev/drm2/ttm/ttm_bo_driver.h>
 #include <dev/drm2/ttm/ttm_placement.h>
+#include <vm/vm_pageout.h>
=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 <dev/drm2/drmP.h>
 #include <dev/drm2/ttm/ttm_bo_driver.h>
 #include <dev/drm2/ttm/ttm_page_alloc.h>
+#include <vm/vm_pageout.h>
=20
 #ifdef TTM_HAS_AGP
 #include <asm/agp.h>
@@ -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--



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