Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb04aa78 authored by Jack Steiner's avatar Jack Steiner Committed by Linus Torvalds
Browse files

sgi-gru: add support for a user to explicitly unload a GRU context



Add support for a user to explicitly unload a GRU context.

Signed-off-by: default avatarJack Steiner <steiner@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e56484da
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/security.h>
#include <asm/pgtable.h>
#include "gru.h"
#include "grutables.h"
@@ -575,6 +576,38 @@ int gru_get_exception_detail(unsigned long arg)
/*
 * User request to unload a context. Content is saved for possible reload.
 */
static int gru_unload_all_contexts(void)
{
	struct gru_thread_state *gts;
	struct gru_state *gru;
	int maxgid, gid, ctxnum;
	int nodesperblade;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	if (num_online_nodes() > 1 &&
			(uv_node_to_blade_id(1) == uv_node_to_blade_id(0)))
		nodesperblade = 2;
	else
		nodesperblade = 1;
	maxgid = GRU_CHIPLETS_PER_BLADE * num_online_nodes() / nodesperblade;
	for (gid = 0; gid < maxgid; gid++) {
		gru = GID_TO_GRU(gid);
		spin_lock(&gru->gs_lock);
		for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
			gts = gru->gs_gts[ctxnum];
			if (gts && mutex_trylock(&gts->ts_ctxlock)) {
				spin_unlock(&gru->gs_lock);
				gru_unload_context(gts, 1);
				gru_unlock_gts(gts);
				spin_lock(&gru->gs_lock);
			}
		}
		spin_unlock(&gru->gs_lock);
	}
	return 0;
}

int gru_user_unload_context(unsigned long arg)
{
	struct gru_thread_state *gts;
@@ -586,6 +619,9 @@ int gru_user_unload_context(unsigned long arg)

	gru_dbg(grudev, "gseg 0x%lx\n", req.gseg);

	if (!req.gseg)
		return gru_unload_all_contexts();

	gts = gru_find_lock_gts(req.gseg);
	if (!gts)
		return -EINVAL;