static struct gru_blade_state *gru_lock_kernel_context(int blade_id)
{
	struct gru_blade_state *bs;
	int bid;

	STAT(lock_kernel_context);
again:
	bid = blade_id < 0 ? uv_numa_blade_id() : blade_id;
	bs = gru_base[bid];

	/*                                                                     */
	down_read(&bs->bs_kgts_sema);
	if (blade_id < 0 && bid != uv_numa_blade_id()) {
		up_read(&bs->bs_kgts_sema);
		goto again;
	}
	if (!bs->bs_kgts || !bs->bs_kgts->ts_gru)
		gru_load_kernel_context(bs, bid);
	return bs;

}
/*
 * Lock & load the kernel context for the specified blade.
 */
static struct gru_blade_state *gru_lock_kernel_context(int blade_id)
{
	struct gru_blade_state *bs;
	int bid;

	STAT(lock_kernel_context);
again:
	bid = blade_id < 0 ? uv_numa_blade_id() : blade_id;
	bs = gru_base[bid];

	/* Handle the case where migration occurred while waiting for the sema */
	down_read(&bs->bs_kgts_sema);
	if (blade_id < 0 && bid != uv_numa_blade_id()) {
		up_read(&bs->bs_kgts_sema);
		goto again;
	}
	if (!bs->bs_kgts || !bs->bs_kgts->ts_gru)
		gru_load_kernel_context(bs, bid);
	return bs;

}
static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
{
	struct gru_blade_state *bs;
	int lcpu;

	BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES);
	preempt_disable();
	bs = gru_base[uv_numa_blade_id()];
	lcpu = uv_blade_processor_id();
	*cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE;
	*dsr = bs->kernel_dsr + lcpu * GRU_NUM_KERNEL_DSR_BYTES;
	return 0;
}
/*
 * Free the current cpus reserved DSR/CBR resources.
 */
static void gru_free_cpu_resources(void *cb, void *dsr)
{
	gru_unlock_kernel_context(uv_numa_blade_id());
	preempt_enable();
}