// 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 <linux/intel-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 = kzalloc(sizeof(*lstat) * DMAR_LATENCY_NUM,
						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;
}
