Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Oct 2016 23:37:13 +0200
From:      =?UTF-8?Q?Jean-S=c3=a9bastien_P=c3=a9dron?= <dumbbell@FreeBSD.org>
To:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Subject:   Linux' struct address_space & FreeBSD's vm_object
Message-ID:  <b5fa5297-cff0-1f20-633e-95facf801bae@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
--wrWAIoLvm0igI7WMDSWPohCt1oPvJaThA
Content-Type: multipart/mixed; boundary="pJfrg5t3ajHA4MuUpoS2t0vSaJq7hhKSj";
 protected-headers="v1"
From: =?UTF-8?Q?Jean-S=c3=a9bastien_P=c3=a9dron?= <dumbbell@FreeBSD.org>
To: "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Message-ID: <b5fa5297-cff0-1f20-633e-95facf801bae@FreeBSD.org>
Subject: Linux' struct address_space & FreeBSD's vm_object

--pJfrg5t3ajHA4MuUpoS2t0vSaJq7hhKSj
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Hi!

I'm tracking a memory leak in the drm-next-4.7 branch [1]. I found the
issue, however, I'm unsure of the solution for now. Let me sum up what I
understand (or what I think I understand :):

In Linux, they use a `struct vm_area_struct` to represent a mapping of
an object. It holds the callback functions (open, close and fault) of
the device driver and the private data to be used with those callbacks.

All `struct vm_area_struct` are stored in a tree in another structure
called `struct address_space` which belongs to the owner of the resource
(an inode in the case of DRM). This structure holds references to pages
loaded from the inode, so it acts as a page cache.

So:
  struct inode
  `-- struct address_space
      |-- tree of pages
      `-- tree of struct vm_area_struct

In DRM, there is a `struct vm_area_struct` for each mapping of each
graphics object. But those mapping are all stored in the same `struct
address_space` belonging to an "anonymous inode" attached to the device.
Furthermore, a DRM driver creates three character devices in /dev for
each real device, and all three character devices use this same
anonymous inode.

Therefore, if I understand correctly, all mappings for all three
character devices use the same list of pages. Thus the memory is shared.

In DRM, when a mapping must be released, eg. i915_gem_release_mmap()
indirectly calls unmap_mapping_range() with the anonymous inode's
`struct address_space`. This function removes all mappings of a given
graphics object, thus removes all `struct vm_area_struct` from `struct
address` which are covered by the specified range.

Currently, on FreeBSD, `struct address_space` is replaced by the
vm_object returned by cdev_pager_allocate(). The first issue is that we
never create the equivalent of `struct address_space` for the global
anonymous inode. Therefore the code responsible for removing mappings
does nothing and mappings & pages are leaked. Anyway, the d_mmap_single
implementation doesn't even try to fill the equivalent of `struct
address_space`.

So that's my understanding of the issue. First, I'm not 100% sure of
what I described and second, I don't see how to implement the same
shared page cache in FreeBSD because a device pager vm_object can't be
shared by multiple mappings (or can it?).

Can you confirm my comprehension? Do you have any ideas to implement that=
?

Thank you very much for your time!

[1] In the development tree for DRM:
https://github.com/FreeBSDDesktop/freebsd-base-graphics

--=20
Jean-S=C3=A9bastien P=C3=A9dron


--pJfrg5t3ajHA4MuUpoS2t0vSaJq7hhKSj--

--wrWAIoLvm0igI7WMDSWPohCt1oPvJaThA
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJYFRaJAAoJEDnpl2Gl/ZTMLwgP/1h6/XVuyXqUCDWPClaJxpIv
RT1+AEwrF7MWxciskSpSMr2mh54Xdjf2wZh6y3ct/LHpXqVmsXqGMDLjCz1dbc0G
yErVXnijI5HuH3Gp+0nRXA2bMv0FxDYrwTtjWnhBvXvDt3N211bFw5iQbbo/6B5+
E75Dy2Y4ux0/CWy22tSyCRFWzEKMckdxK3BTCkKdOqZtLRRrjq6qV+4OYYJxNqdQ
XbY6NUKEBXz+jrRjewOuqd3cq9UmEmLYk09x8xwpn8EBKiIRG9Va4kigJTv9ZjJQ
ZztHipWQrz9A/rin8CUVuxVhLZos6BDz+a7drtG1ZldUfgofFKK6U7jnxhE4qAt5
Z0NFU5Fd+bu7qhGEtWTjzZywTmPjtboI06BYknRS8ckZnTOlhfb2kVFO7sIOA2yF
Ui4yHZAn9DRHvQQv2+HqKIxiplRjCj3Fpu6aXYM6tNmZQG/hok+GNGmGEjFDmJgh
PZZr6JHfv/DXn2eUoHJdTq7y0qRTMUHG84ZsRn0lZhgptwFsGcmc6Bhr/BiFODvi
Hyq8cbnjsFNDVG98ZWg1ggw26QttgZo4bCWTMGRd26sSw1WW5QZP90f2H/ASgJlU
Ymirz+wGEdZ9hYUe3UazYnRSc766bmy553FoAPSDOaxEctMemJBZijJVT4gyrFUy
+AWW+jWlhjaIf2cCb8bZ
=n94E
-----END PGP SIGNATURE-----

--wrWAIoLvm0igI7WMDSWPohCt1oPvJaThA--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?b5fa5297-cff0-1f20-633e-95facf801bae>