// SPDX-License-Identifier: GPL-2.0
/*
 * perf.c - performance monitor
 *
 * Copyright (C) 2021 Intel Corporation
 *
 * Author: Lu Baolu <baolu.lu@linux.intel.com>
 *         Fenghua Yu <fenghua.yu@intel.com>
 */

#include <linux/spinlock.h>

#include "iommu.h"
#include "perf.h"

static DEFINE_SPINLOCK(latency_lock);

bool dmar_latency_enabled(struct intel_iommu *iommu, enum latency_type type)
{
	struct latency_statistic *lstat = iommu->perf_statistic;

	return lstat && lstat[type].enabled;
}

int dmar_latency_enable(struct intel_iommu *iommu, enum latency_type type)
{
	struct latency_statistic *lstat;
	unsigned long flags;
	int ret = -EBUSY;

	if (dmar_latency_enabled(iommu, type))
		return 0;

	spin_lock_irqsave(&latency_lock, flags);
	if (!iommu->perf_statistic) {
		iommu->perf_statistic = kcalloc(DMAR_LATENCY_NUM, sizeof(*lstat),
						GFP_ATOMIC);
		if (!iommu->perf_statistic) {
			ret = -ENOMEM;
			goto unlock_out;
		}
	}

	lstat = iommu->perf_statistic;

	if (!lstat[type].enabled) {
		lstat[type].enabled = true;
		lstat[type].counter[COUNTS_MIN] = UINT_MAX;
		ret = 0;
	}
unlock_out:
	spin_unlock_irqrestore(&latency_lock, flags);

	return ret;
}

void dmar_latency_disable(struct intel_iommu *iommu, enum latency_type type)
{
	struct latency_statistic *lstat = iommu->perf_statistic;
	unsigned long flags;

	if (!dmar_latency_enabled(iommu, type))
		return;

	spin_lock_irqsave(&latency_lock, flags);
	memset(&lstat[type], 0, sizeof(*lstat) * DMAR_LATENCY_NUM);
	spin_unlock_irqrestore(&latency_lock, flags);
}

void dmar_latency_update(struct intel_iommu *iommu, enum latency_type type, u64 latency)
{
	struct latency_statistic *lstat = iommu->perf_statistic;
	unsigned long flags;
	u64 min, max;

	if (!dmar_latency_enabled(iommu, type))
		return;

	spin_lock_irqsave(&latency_lock, flags);
	if (latency < 100)
		lstat[type].counter[COUNTS_10e2]++;
	else if (latency < 1000)
		lstat[type].counter[COUNTS_10e3]++;
	else if (latency < 10000)
		lstat[type].counter[COUNTS_10e4]++;
	else if (latency < 100000)
		lstat[type].counter[COUNTS_10e5]++;
	else if (latency < 1000000)
		lstat[type].counter[COUNTS_10e6]++;
	else if (latency < 10000000)
		lstat[type].counter[COUNTS_10e7]++;
	else
		lstat[type].counter[COUNTS_10e8_plus]++;

	min = lstat[type].counter[COUNTS_MIN];
	max = lstat[type].counter[COUNTS_MAX];
	lstat[type].counter[COUNTS_MIN] = min_t(u64, min, latency);
	lstat[type].counter[COUNTS_MAX] = max_t(u64, max, latency);
	lstat[type].counter[COUNTS_SUM] += latency;
	lstat[type].samples++;
	spin_unlock_irqrestore(&latency_lock, flags);
}

static char *latency_counter_names[] = {
	"                  <0.1us",
	"   0.1us-1us", "    1us-10us", "  10us-100us",
	"   100us-1ms", "    1ms-10ms", "      >=10ms",
	"     min(us)", "     max(us)", " average(us)"
};

static char *latency_type_names[] = {
	"   inv_iotlb", "  inv_devtlb", "     inv_iec",
	"     svm_prq"
};

int dmar_latency_snapshot(struct intel_iommu *iommu, char *str, size_t size)
{
	struct latency_statistic *lstat = iommu->perf_statistic;
	unsigned long flags;
	int bytes = 0, i, j;

	memset(str, 0, size);

	for (i = 0; i < COUNTS_NUM; i++)
		bytes += snprintf(str + bytes, size - bytes,
				  "%s", latency_counter_names[i]);

	spin_lock_irqsave(&latency_lock, flags);
	for (i = 0; i < DMAR_LATENCY_NUM; i++) {
		if (!dmar_latency_enabled(iommu, i))
			continue;

		bytes += snprintf(str + bytes, size - bytes,
				  "\n%s", latency_type_names[i]);

		for (j = 0; j < COUNTS_NUM; j++) {
			u64 val = lstat[i].counter[j];

			switch (j) {
			case COUNTS_MIN:
				if (val == UINT_MAX)
					val = 0;
				else
					val = div_u64(val, 1000);
				break;
			case COUNTS_MAX:
				val = div_u64(val, 1000);
				break;
			case COUNTS_SUM:
				if (lstat[i].samples)
					val = div_u64(val, (lstat[i].samples * 1000));
				else
					val = 0;
				break;
			default:
				break;
			}

			bytes += snprintf(str + bytes, size - bytes,
					  "%12lld", val);
		}
	}
	spin_unlock_irqrestore(&latency_lock, flags);

	return bytes;
}
