summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--applications/luci-app-irqbalance/Makefile13
-rw-r--r--applications/luci-app-irqbalance/htdocs/luci-static/resources/view/irqbalance.js116
-rw-r--r--applications/luci-app-irqbalance/root/etc/uci-defaults/90_luci-irqbalance10
-rw-r--r--applications/luci-app-irqbalance/root/usr/share/luci/menu.d/luci-app-irqbalance.json21
-rw-r--r--applications/luci-app-irqbalance/root/usr/share/rpcd/acl.d/luci-app-irqbalance.json25
5 files changed, 185 insertions, 0 deletions
diff --git a/applications/luci-app-irqbalance/Makefile b/applications/luci-app-irqbalance/Makefile
new file mode 100644
index 0000000000..91e97cdc39
--- /dev/null
+++ b/applications/luci-app-irqbalance/Makefile
@@ -0,0 +1,13 @@
+# Copyright 2023 Puran Lyu <pl2355@nyu.edu>
+# This is free software, licensed under the Apache License, Version 2.0.
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=LuCI support for irqbalance
+LUCI_DEPENDS:=+luci-base +irqbalance
+
+PKG_LICENSE:=Apache-2.0
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-irqbalance/htdocs/luci-static/resources/view/irqbalance.js b/applications/luci-app-irqbalance/htdocs/luci-static/resources/view/irqbalance.js
new file mode 100644
index 0000000000..280b6f19c7
--- /dev/null
+++ b/applications/luci-app-irqbalance/htdocs/luci-static/resources/view/irqbalance.js
@@ -0,0 +1,116 @@
+'use strict';
+'require view';
+'require fs';
+'require form';
+'require ui';
+'require rpc';
+
+const callServiceList = rpc.declare({
+ object: 'service',
+ method: 'list',
+ params: ['name'],
+ expect: { '': {} },
+});
+
+function getServiceStatus() {
+ return L.resolveDefault(callServiceList('irqbalance'), {}).then(function (res) {
+ try {
+ return res['irqbalance']['instances']['irqbalance']['running'];
+ } catch (e) {
+ return false;
+ }
+ });
+}
+
+function renderStatus(isRunning) {
+ const spanTemp = '<span style="color:%s"><strong>%s</strong></span>';
+
+ return isRunning
+ ? String.format(spanTemp, 'green', _('RUNNING'))
+ : String.format(spanTemp, 'red', _('NOT RUNNING'));
+}
+
+return view.extend({
+ load() {
+ return L.resolveDefault(fs.read_direct('/proc/interrupts'));
+ },
+
+ render(data) {
+ const cpuNum = data.match(/\bCPU\d+\b/g).map(i => i.slice(3)), // cpuNum = data.match(/(?<=\bCPU)\d+\b/g), // Safari did not support RegExp lookbehind assertion before version 16.4.
+ irqNum = data.match(/\b\d+(?=: )/g);
+ let m, s, o;
+
+ m = new form.Map('irqbalance', _('irqbalance'), _('The purpose of irqbalance is to distribute hardware interrupts across processors/cores on a multiprocessor/multicore system in order to increase performance.'));
+
+ s = m.section(form.NamedSection);
+ s.anonymous = true;
+ s.render = function () {
+ L.Poll.add(function () {
+ return L.resolveDefault(getServiceStatus()).then(function (res) {
+ const view = document.getElementById('status');
+ view.innerHTML = renderStatus(res);
+ });
+ });
+
+ return E('div', { class: 'cbi-section' }, [
+ E('p', { id: 'status' }, _('Loading...'))
+ ]);
+ }
+
+ s = m.section(form.TypedSection, 'irqbalance', _('Snapshot of current IRQs'));
+ s.anonymous = true;
+
+ s = m.section(form.NamedSection);
+ s.anonymous = true;
+ s.render = function () {
+ const snapshot = new ui.Textarea(data.slice(0, -1), {
+ readonly: true,
+ placeholder: _('Loading...'),
+ monospace: true,
+ rows: data.split('\n').length - 1,
+ });
+ return snapshot.render();
+ }
+
+ s = m.section(form.TypedSection, 'irqbalance', _('General settings'));
+ s.anonymous = true;
+
+ o = s.option(form.Flag, 'enabled', _('Enable'));
+ o.default = '0';
+ o.rmempty = false;
+
+ o = s.option(form.Value, 'deepestcache', _('Deepest cache'), _('Cache level at which irqbalance partitions cache domains.'));
+ o.placeholder = '2';
+ o.datatype = 'uinteger';
+ o.optional = true;
+
+ o = s.option(form.Value, 'interval', _('Interval'), _('Value in seconds.'));
+ o.placeholder = '10';
+ o.datatype = 'uinteger';
+ o.optional = true;
+
+ o = s.option(form.Value, 'banned_cpulist', _('Exclude CPUs'), _('List of CPUs to ignore, can be an integer or integers separated by commas.') + '<br />' + _('Valid values: %s.').format(cpuNum.join(', ')));
+ o.placeholder = '0';
+ o.optional = true;
+ o.validate = function (section_id, value) {
+ for (const i of value.split(',')) {
+ if (!cpuNum.includes(i) && i != '') {
+ return _('Invalid');
+ }
+ }
+ return true;
+ }
+
+ o = s.option(form.DynamicList, 'banirq', _('Exclude IRQs'), _('List of IRQs to ignore.') + '<br />' + _('Valid values: %s.').format(irqNum.join(', ')));
+ o.placeholder = '36';
+ o.datatype = 'uinteger';
+ o.optional = true;
+ o.validate = function (section_id, value) {
+ return !irqNum.includes(value) && value != ''
+ ? _('Invalid')
+ : true;
+ }
+
+ return m.render();
+ }
+});
diff --git a/applications/luci-app-irqbalance/root/etc/uci-defaults/90_luci-irqbalance b/applications/luci-app-irqbalance/root/etc/uci-defaults/90_luci-irqbalance
new file mode 100644
index 0000000000..e6ec84c4db
--- /dev/null
+++ b/applications/luci-app-irqbalance/root/etc/uci-defaults/90_luci-irqbalance
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+uci -q batch <<-EOF >/dev/null
+ delete ucitrack.@irqbalance[-1]
+ add ucitrack irqbalance
+ set ucitrack.@irqbalance[-1].init=irqbalance
+ commit ucitrack
+EOF
+
+exit 0
diff --git a/applications/luci-app-irqbalance/root/usr/share/luci/menu.d/luci-app-irqbalance.json b/applications/luci-app-irqbalance/root/usr/share/luci/menu.d/luci-app-irqbalance.json
new file mode 100644
index 0000000000..6a4b29589b
--- /dev/null
+++ b/applications/luci-app-irqbalance/root/usr/share/luci/menu.d/luci-app-irqbalance.json
@@ -0,0 +1,21 @@
+{
+ "admin/services/irqbalance": {
+ "title": "irqbalance",
+ "order": 90,
+ "action": {
+ "type": "view",
+ "path": "irqbalance"
+ },
+ "depends": {
+ "acl": [
+ "luci-app-irqbalance"
+ ],
+ "uci": {
+ "irqbalance": true
+ },
+ "fs": {
+ "/proc/interrupts": "file"
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/applications/luci-app-irqbalance/root/usr/share/rpcd/acl.d/luci-app-irqbalance.json b/applications/luci-app-irqbalance/root/usr/share/rpcd/acl.d/luci-app-irqbalance.json
new file mode 100644
index 0000000000..44b6f5ff23
--- /dev/null
+++ b/applications/luci-app-irqbalance/root/usr/share/rpcd/acl.d/luci-app-irqbalance.json
@@ -0,0 +1,25 @@
+{
+ "luci-app-irqbalance": {
+ "description": "Grant UCI access for luci-app-irqbalance",
+ "read": {
+ "file": {
+ "/proc/interrupts": [
+ "read"
+ ]
+ },
+ "ubus": {
+ "service": [
+ "list"
+ ]
+ },
+ "uci": [
+ "irqbalance"
+ ]
+ },
+ "write": {
+ "uci": [
+ "irqbalance"
+ ]
+ }
+ }
+} \ No newline at end of file