diff options
author | David Miller <davem@davemloft.net> | 2009-02-18 15:41:02 -0800 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-03-13 14:24:03 +1000 |
commit | f1a2a9b6189f9f5c27672d4d32fec9492c6486b2 (patch) | |
tree | a85f1d2e84afd78a6dd188b048f7dfee9607e510 /fs/configfs/dir.c | |
parent | d30333bbabb4a2cfad1f1a45c48a4e4d0065c1f6 (diff) |
drm: Preserve SHMLBA bits in hash key for _DRM_SHM mappings.
Platforms such as sparc64 have D-cache aliasing issues. We
cannot allow virtual mappings in different contexts to be such
that two cache lines can be loaded for the same backing data.
Updates to one cache line won't be seen by accesses to the other
cache line.
Code in sparc64 and other architectures solve this problem by
making sure that all userland mappings of MAP_SHARED objects have
the same virtual address base. They implement this by keying
off of the page offset, and using that to choose a suitably
consistent virtual address for mmap() requests.
Making things even worse, getting this wrong on sparc64 can result
in hangs during DRM lock acquisition. This is because, at least on
UltraSPARC-III, normal loads consult the D-cache but atomics such
as 'cas' (which is what cmpxchg() is implement using) only consult
the L2 cache. So if a D-cache alias is inserted, the load can
see different data than the atomic, and we'll loop forever because
the atomic compare-and-exchange will never complete successfully.
So to make this all work properly, we need to make sure that the
hash address computed by drm_map_handle() preserves the SHMLBA
relevant bits, and that's what this patch does for _DRM_SHM mappings.
As a historical note, many years ago this bug didn't exist because we
used to just use the low 32-bits of the address as the hash and just
hope for the best. This preserved the SHMLBA bits properly. But when
the hashtab code was added to DRM, this was no longer the case.
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'fs/configfs/dir.c')
0 files changed, 0 insertions, 0 deletions