Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jul 2012 21:17:53 +1000
From:      Peter Jeremy <peter@rulingia.com>
To:        freebsd-hackers@freebsd.org
Subject:   contigmalloc() breaking Xorg
Message-ID:  <20120703111753.GB72292@server.rulingia.com>

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

--jI8keyz6grp/JLjh
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I have a reasonably recent 8-stable/amd64 system (r237444) with a "ATI
Radeon HD 2400 Pro", xorg-server-1.10.6,1 and xf86-video-ati-6.14.3_1
8GB RAM and ZFS.  I'm seeing fairly consistent problems with Xorg
spinning in swwrt for long periods (I've seen =BDhr) and then failing.
The resultant Xorg.0.log shows (eg):
[854259.962] (EE) RADEON(0): [pci] Out of memory (-12)

That message comes from
xf86-video-ati-6.14.3/src/radeon_dri.c:RADEONDRIPciInit() and the -12
indicates ENOMEM.  That code (indirectly) issues DRM_IOCTL_SG_ALLOC
and winds up in sys/dev/drm/drm_scatter.c:drm_sg_alloc(), which uses
bus_dma_tag_create(), bus_dmamem_alloc() and bus_dmamap_load() to
actually allocate memory below 4GB.

Setting hw.dri.0.debug shows that it's trying to allocate 32MB:
Jul  3 18:57:49 server kernel: [drm:pid72128:drm_ioctl] pid=3D72128, cmd=3D=
0xc0106438, nr=3D0x38, dev 0xffffff000246ee00, auth=3D1
Jul  3 18:57:49 server kernel: [drm:pid72128:drm_sg_alloc_ioctl]=20
Jul  3 18:57:49 server kernel: [drm:pid72128:drm_sg_alloc] sg size=3D335544=
32 pages=3D8192
Jul  3 19:28:09 server kernel: [drm:pid72128:drm_ioctl]     returning 12
[note the timestamps]

Whilst drm_sg_alloc() allows non-contiguous allocation (the code just
wants 8192 pages), bus_dma(9) states: "The current implementation of
bus_dmamem_alloc() will allocate all requests as a single segment."
(and this is the same in 10-current).  bus_dmamem_alloc() for a region
greater than one page uses contigmalloc().

I believe that Xorg spinning in swwrt is a regression but I don't have
a good idea for when it started (and
http://lists.freebsd.org/pipermail/freebsd-stable/2011-February/061369.html
suggests that it's been occurring for quite a while).  For that matter
contigmalloc() also seems to have a long history of causing problems
with other parts of FreeBSD - I first crossed swords with it 7=BD years
ago (when it was causing panics in umass(4)).

Previously, the work-around for contigmalloc() issues was to ensure
that the appropriate contigmalloc() calls occurred shortly after a
reboot - before RAM got too fragmented.  That doesn't appear to work
here because it looks like Xorg releases and (tries to) re-allocates
the memory during a reset (ie on logout).  It is a _serious_ nuisance
having to reboot because I fumbled my password...

Can anyone suggest a way forward?  Note that additional RAM isn't an
option for this box.

How difficult would it be to modify bus_dmamem_alloc() [at least on
x86] to handle multi-segment allocations?

Does anyone have a tool that can display physical RAM allocation?
This would at least allow me to identify offending allocations.
http://lists.freebsd.org/pipermail/freebsd-hackers/2011-February/thread.html
asks the same question but just peters out.

--=20
Peter Jeremy

--jI8keyz6grp/JLjh
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)

iEUEARECAAYFAk/y1OEACgkQ/opHv/APuIc7IwCVFQXPX6b1dStc/nTA4koh8fnm
AACgwBAFfQdZF0j5omNH8w5Jgq1tZPU=
=Oo8S
-----END PGP SIGNATURE-----

--jI8keyz6grp/JLjh--



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