/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * GPL HEADER END
 */
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2012, 2015 Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * Author: liang@whamcloud.com
 */

#define DEBUG_SUBSYSTEM S_LNET

#include <linux/libcfs/libcfs.h>

/** destroy cpu-partition lock, see libcfs_private.h for more detail */
void
cfs_percpt_lock_free(struct cfs_percpt_lock *pcl)
{
	LASSERT(pcl->pcl_locks);
	LASSERT(!pcl->pcl_locked);

	cfs_percpt_free(pcl->pcl_locks);
	LIBCFS_FREE(pcl, sizeof(*pcl));
}
EXPORT_SYMBOL(cfs_percpt_lock_free);

/**
 * create cpu-partition lock, see libcfs_private.h for more detail.
 *
 * cpu-partition lock is designed for large-scale SMP system, so we need to
 * reduce cacheline conflict as possible as we can, that's the
 * reason we always allocate cacheline-aligned memory block.
 */
struct cfs_percpt_lock *
cfs_percpt_lock_create(struct cfs_cpt_table *cptab,
		       struct lock_class_key *keys)
{
	struct cfs_percpt_lock *pcl;
	spinlock_t *lock;
	int i;

	/* NB: cptab can be NULL, pcl will be for HW CPUs on that case */
	LIBCFS_ALLOC(pcl, sizeof(*pcl));
	if (!pcl)
		return NULL;

	pcl->pcl_cptab = cptab;
	pcl->pcl_locks = cfs_percpt_alloc(cptab, sizeof(*lock));
	if (!pcl->pcl_locks) {
		LIBCFS_FREE(pcl, sizeof(*pcl));
		return NULL;
	}

	if (!keys)
		CWARN("Cannot setup class key for percpt lock, you may see recursive locking warnings which are actually fake.\n");

	cfs_percpt_for_each(lock, i, pcl->pcl_locks) {
		spin_lock_init(lock);
		if (keys)
			lockdep_set_class(lock, &keys[i]);
	}

	return pcl;
}
EXPORT_SYMBOL(cfs_percpt_lock_create);

/**
 * lock a CPU partition
 *
 * \a index != CFS_PERCPT_LOCK_EX
 *     hold private lock indexed by \a index
 *
 * \a index == CFS_PERCPT_LOCK_EX
 *     exclusively lock @pcl and nobody can take private lock
 */
void
cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index)
	__acquires(pcl->pcl_locks)
{
	int ncpt = cfs_cpt_number(pcl->pcl_cptab);
	int i;

	LASSERT(index >= CFS_PERCPT_LOCK_EX && index < ncpt);

	if (ncpt == 1) {
		index = 0;
	} else { /* serialize with exclusive lock */
		while (pcl->pcl_locked)
			cpu_relax();
	}

	if (likely(index != CFS_PERCPT_LOCK_EX)) {
		spin_lock(pcl->pcl_locks[index]);
		return;
	}

	/* exclusive lock request */
	for (i = 0; i < ncpt; i++) {
		spin_lock(pcl->pcl_locks[i]);
		if (!i) {
			LASSERT(!pcl->pcl_locked);
			/* nobody should take private lock after this
			 * so I wouldn't starve for too long time
			 */
			pcl->pcl_locked = 1;
		}
	}
}
EXPORT_SYMBOL(cfs_percpt_lock);

/** unlock a CPU partition */
void
cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index)
	__releases(pcl->pcl_locks)
{
	int ncpt = cfs_cpt_number(pcl->pcl_cptab);
	int i;

	index = ncpt == 1 ? 0 : index;

	if (likely(index != CFS_PERCPT_LOCK_EX)) {
		spin_unlock(pcl->pcl_locks[index]);
		return;
	}

	for (i = ncpt - 1; i >= 0; i--) {
		if (!i) {
			LASSERT(pcl->pcl_locked);
			pcl->pcl_locked = 0;
		}
		spin_unlock(pcl->pcl_locks[i]);
	}
}
EXPORT_SYMBOL(cfs_percpt_unlock);
