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

Commit 4f230ed4 authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan
Browse files

drivers: rmnet_shs: Freq Boost Feature



Add option to boost a CPU when switching in order
to avoid OOO packets more effectively.

CRs-Fixed: 2469507
Change-Id: I7166c32a7b5be57d0ec106e24a67cbc1b586f132
Acked-by: default avatarRaul Martinez <mraul@qti.qualcomm.com>
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent 90c76228
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ LOCAL_CLANG :=true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
LOCAL_MODULE := rmnet_shs.ko

LOCAL_SRC_FILES := rmnet_shs_main.c rmnet_shs_config.c rmnet_shs_wq.c
LOCAL_SRC_FILES := rmnet_shs_main.c rmnet_shs_config.c rmnet_shs_wq.c rmnet_shs_freq.c

RMNET_SHS_BLD_DIR := ../../vendor/qcom/opensource/data-kernel/drivers/rmnet/shs
DLKM_DIR := ./device/qcom/common/dlkm
+1 −1
Original line number Diff line number Diff line
obj-m += rmnet_shs.o
rmnet_shs-y := rmnet_shs_config.o rmnet_shs_main.o rmnet_shs_wq.o
rmnet_shs-y := rmnet_shs_config.o rmnet_shs_main.o rmnet_shs_wq.o rmnet_shs_freq.o
+3 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#ifndef _RMNET_SHS_H_
#define _RMNET_SHS_H_

#include "rmnet_shs_freq.h"

#include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h>
#include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h>
#include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h>
@@ -32,6 +34,7 @@
#define RMNET_SHS_MAX_SKB_INACTIVE_TSEC 30
#define MAX_SILVER_CORES 4
#define MAX_CPUS  8
#define PERF_MASK 0xF0

/* RPS mask change's Default core for orphaned CPU flows */
#define MAIN_CORE 0
+156 −0
Original line number Diff line number Diff line
/* Copyright (c) 2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 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 for more details.
 *
 * RMNET Data Smart Hash stamping solution
 *
 */
#include <linux/module.h>
#include "rmnet_shs.h"
#include "rmnet_shs_freq.h"

#include <linux/cpufreq.h>
#include <linux/cpu.h>

#define MAX_FREQ INT_MAX
#define MIN_FREQ 0
#define BOOST_FREQ MAX_FREQ

struct cpu_freq {
	unsigned int freq_floor;
	unsigned int freq_ceil;

};

unsigned int rmnet_shs_freq_enable __read_mostly = 1;
module_param(rmnet_shs_freq_enable, uint, 0644);
MODULE_PARM_DESC(rmnet_shs_freq_enable, "Enable/disable freq boost feature");

struct workqueue_struct *shs_boost_wq;
static DEFINE_PER_CPU(struct cpu_freq, cpu_boosts);
static struct work_struct boost_cpu;

static int rmnet_shs_freq_notify(struct notifier_block *nb,
				 unsigned long val,
				 void *data)
{
	struct cpufreq_policy *policy = data;
	unsigned int cpu = policy->cpu;
	struct cpu_freq *boost = &per_cpu(cpu_boosts, cpu);

	switch (val) {
	case CPUFREQ_ADJUST:
		if (rmnet_shs_freq_enable) {
			cpufreq_verify_within_limits(policy,
						     boost->freq_floor,
						     MAX_FREQ);
			trace_rmnet_freq_update(cpu, policy->min,
						policy->max);
		}
		break;
	}

	return NOTIFY_OK;
}

static struct notifier_block freq_boost_nb = {
	.notifier_call = rmnet_shs_freq_notify,
};

static void update_cpu_policy(struct work_struct *work)
{
	unsigned int i;

	get_online_cpus();
	for_each_online_cpu(i) {
		cpufreq_update_policy(i);
	}

	put_online_cpus();
}

void rmnet_shs_reset_freq(void)
{
	struct cpu_freq *boost;
	int i;

	for_each_possible_cpu(i) {
		boost = &per_cpu(cpu_boosts, i);
		boost->freq_floor = MIN_FREQ;
		boost->freq_ceil = MAX_FREQ;
	}
}

void rmnet_shs_boost_cpus()
{
	struct cpu_freq *boost;
	int i;

	for_each_possible_cpu(i) {

		if ((1 << i) & PERF_MASK)
			continue;
		boost = &per_cpu(cpu_boosts, i);
		boost->freq_floor = BOOST_FREQ;
		boost->freq_ceil = MAX_FREQ;
		trace_rmnet_freq_boost(i, boost->freq_floor);
	}

	if (work_pending(&boost_cpu))
		return;

	queue_work(shs_boost_wq, &boost_cpu);
}

void rmnet_shs_reset_cpus()
{
	struct cpu_freq *boost;
	int i;

	for_each_possible_cpu(i) {

		if ((1 << i) & PERF_MASK)
			continue;
		boost = &per_cpu(cpu_boosts, i);
		boost->freq_floor = MIN_FREQ;
		boost->freq_ceil = MAX_FREQ;
		trace_rmnet_freq_reset(i, boost->freq_floor);
	}
	if (work_pending(&boost_cpu))
		return;

	queue_work(shs_boost_wq, &boost_cpu);
}

int rmnet_shs_freq_init(void)
{
	shs_boost_wq = alloc_workqueue("shs_boost_wq", WQ_HIGHPRI, 0);

	if (!shs_boost_wq)
		return -EFAULT;
	INIT_WORK(&boost_cpu, update_cpu_policy);

	if (rmnet_shs_freq_enable)
		cpufreq_register_notifier(&freq_boost_nb,
					  CPUFREQ_POLICY_NOTIFIER);
	rmnet_shs_reset_freq();
	return 0;
}

int rmnet_shs_freq_exit(void)
{
	rmnet_shs_reset_freq();
	cancel_work_sync(&boost_cpu);

	if (rmnet_shs_freq_enable)
		cpufreq_unregister_notifier(&freq_boost_nb,
					    CPUFREQ_POLICY_NOTIFIER);
	return 0;
}
+24 −0
Original line number Diff line number Diff line
/* Copyright (c) 2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 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 for more details.
 *
 * RMNET Data Smart Hash solution
 *
 */

#ifndef _RMNET_SHS_FREQ_H_
#define _RMNET_SHS_FREQ_H_

int rmnet_shs_freq_init(void);
int rmnet_shs_freq_exit(void);
void rmnet_shs_boost_cpus(void);
void rmnet_shs_reset_cpus(void);

#endif
Loading