Commit 611f3186 authored by Matthew Wilcox's avatar Matthew Wilcox
Browse files

XArray: Unify xa_store and __xa_store



Saves around 115 bytes on a tinyconfig build and reduces the amount
of code duplication in the XArray implementation.

Signed-off-by: default avatarMatthew Wilcox <willy@infradead.org>
parent 84e5acb7
Loading
Loading
Loading
Loading
+25 −33
Original line number Diff line number Diff line
@@ -1361,23 +1361,21 @@ void *xa_erase(struct xarray *xa, unsigned long index)
EXPORT_SYMBOL(xa_erase);

/**
 * xa_store() - Store this entry in the XArray.
 * __xa_store() - Store this entry in the XArray.
 * @xa: XArray.
 * @index: Index into array.
 * @entry: New entry.
 * @gfp: Memory allocation flags.
 *
 * After this function returns, loads from this index will return @entry.
 * Storing into an existing multislot entry updates the entry of every index.
 * The marks associated with @index are unaffected unless @entry is %NULL.
 * You must already be holding the xa_lock when calling this function.
 * It will drop the lock if needed to allocate memory, and then reacquire
 * it afterwards.
 *
 * Context: Process context.  Takes and releases the xa_lock.  May sleep
 * if the @gfp flags permit.
 * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry
 * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation
 * failed.
 * Context: Any context.  Expects xa_lock to be held on entry.  May
 * release and reacquire xa_lock if @gfp flags permit.
 * Return: The old entry at this index or xa_err() if an error happened.
 */
void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
{
	XA_STATE(xas, xa, index);
	void *curr;
@@ -1386,49 +1384,43 @@ void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
		return XA_ERROR(-EINVAL);

	do {
		xas_lock(&xas);
		curr = xas_store(&xas, entry);
		if (xa_track_free(xa) && entry)
			xas_clear_mark(&xas, XA_FREE_MARK);
		xas_unlock(&xas);
	} while (xas_nomem(&xas, gfp));
	} while (__xas_nomem(&xas, gfp));

	return xas_result(&xas, curr);
}
EXPORT_SYMBOL(xa_store);
EXPORT_SYMBOL(__xa_store);

/**
 * __xa_store() - Store this entry in the XArray.
 * xa_store() - Store this entry in the XArray.
 * @xa: XArray.
 * @index: Index into array.
 * @entry: New entry.
 * @gfp: Memory allocation flags.
 *
 * You must already be holding the xa_lock when calling this function.
 * It will drop the lock if needed to allocate memory, and then reacquire
 * it afterwards.
 * After this function returns, loads from this index will return @entry.
 * Storing into an existing multislot entry updates the entry of every index.
 * The marks associated with @index are unaffected unless @entry is %NULL.
 *
 * Context: Any context.  Expects xa_lock to be held on entry.  May
 * release and reacquire xa_lock if @gfp flags permit.
 * Return: The old entry at this index or xa_err() if an error happened.
 * Context: Any context.  Takes and releases the xa_lock.
 * May sleep if the @gfp flags permit.
 * Return: The old entry at this index on success, xa_err(-EINVAL) if @entry
 * cannot be stored in an XArray, or xa_err(-ENOMEM) if memory allocation
 * failed.
 */
void *__xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
{
	XA_STATE(xas, xa, index);
	void *curr;

	if (WARN_ON_ONCE(xa_is_internal(entry)))
		return XA_ERROR(-EINVAL);

	do {
		curr = xas_store(&xas, entry);
		if (xa_track_free(xa) && entry)
			xas_clear_mark(&xas, XA_FREE_MARK);
	} while (__xas_nomem(&xas, gfp));
	xa_lock(xa);
	curr = __xa_store(xa, index, entry, gfp);
	xa_unlock(xa);

	return xas_result(&xas, curr);
	return curr;
}
EXPORT_SYMBOL(__xa_store);
EXPORT_SYMBOL(xa_store);

/**
 * __xa_cmpxchg() - Store this entry in the XArray.