diff options
author | Matthew Wilcox <willy@infradead.org> | 2019-02-20 17:30:49 +0100 |
---|---|---|
committer | Matthew Wilcox <willy@infradead.org> | 2019-02-20 23:08:54 +0100 |
commit | b38f6c50270683abf35a388f82cafecce971a003 (patch) | |
tree | 0db0d39cf82d0f1996b28056668ebeabc8e58add /lib/xarray.c | |
parent | XArray: Mark xa_insert and xa_reserve as must_check (diff) | |
download | linux-b38f6c50270683abf35a388f82cafecce971a003.tar.xz linux-b38f6c50270683abf35a388f82cafecce971a003.zip |
XArray: Fix xa_release in allocating arrays
xa_cmpxchg() was a little too magic in turning ZERO entries into NULL,
and would leave the entry set to the ZERO entry instead of releasing
it for future use. After careful review of existing users of
xa_cmpxchg(), change the semantics so that it does not translate either
incoming argument from NULL into ZERO entries.
Add several tests to the test-suite to make sure this problem doesn't
come back.
Reported-by: Jason Gunthorpe <jgg@ziepe.ca>
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'lib/xarray.c')
-rw-r--r-- | lib/xarray.c | 6 |
1 files changed, 1 insertions, 5 deletions
diff --git a/lib/xarray.c b/lib/xarray.c index 89e37ac50850..b9a6cf42feee 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -1429,16 +1429,12 @@ void *__xa_cmpxchg(struct xarray *xa, unsigned long index, if (WARN_ON_ONCE(xa_is_advanced(entry))) return XA_ERROR(-EINVAL); - if (xa_track_free(xa) && !entry) - entry = XA_ZERO_ENTRY; do { curr = xas_load(&xas); - if (curr == XA_ZERO_ENTRY) - curr = NULL; if (curr == old) { xas_store(&xas, entry); - if (xa_track_free(xa)) + if (xa_track_free(xa) && entry && !curr) xas_clear_mark(&xas, XA_FREE_MARK); } } while (__xas_nomem(&xas, gfp)); |