Skip to content

Commit 36001ff

Browse files
committed
rh_flags: Rename rh_features to rh_flags
JIRA: https://issues.redhat.com/browse/RHEL-122981 Conflicts: Minor context difference due to RHEL-only commit c7db2ac ("kernel: Add redhat code") This patch is a backport of the following RHEL-only commit: commit 659bcb087790263f589f90a4b6cd75a3f2c8a89c Author: Ricardo Robaina <rrobaina@redhat.com> Date: Fri May 10 20:31:21 2024 -0300 rh_flags: Rename rh_features to rh_flags JIRA: https://issues.redhat.com/browse/RHEL-32987 Conflicts: - Unrelated hunks dropped - Minor context differences due to 76106c6dac3 ('add support for rh_features') and d756b75a7f90 ('rh_features: move rh_features entry to sys/kernel') This patch is a backport of the following upstream commit: commit dd996f09078abf3d8a8ef1ac77616297bc77b598 Author: Prarit Bhargava <prarit@redhat.com> Date: Tue Nov 9 09:52:38 2021 -0500 rh_flags: Rename rh_features to rh_flags Bugzilla: https://bugzilla.redhat.com/2021700 Upstream Status: RHEL only Features implies that this code can only be used to indicate functionality, however, I'd like to also use these as debug flags. Rename rh_features to rh_flags, and change the output to indicate "Red Hat Flags" instead of "Features". Signed-off-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Ricardo Robaina <rrobaina@redhat.com> Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
1 parent f42481d commit 36001ff

File tree

6 files changed

+153
-148
lines changed

6 files changed

+153
-148
lines changed

include/linux/rh_features.h

Lines changed: 0 additions & 29 deletions
This file was deleted.

include/linux/rh_flags.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* rh_flags.h -- Red Hat flags tracking
4+
*
5+
* Copyright (c) 2018 Red Hat, Inc. -- Jiri Benc <jbenc@redhat.com>
6+
*
7+
* The intent of the flag tracking is to provide better and more focused
8+
* support. Only those flags that are of a special interest for customer
9+
* support should be tracked.
10+
*
11+
* THE FLAGS DO NOT EXPRESS ANY SUPPORT POLICIES.
12+
*/
13+
14+
#ifndef _LINUX_RH_FLAGS_H
15+
#define _LINUX_RH_FLAGS_H
16+
17+
#if defined CONFIG_RHEL_DIFFERENCES
18+
bool __rh_add_flag(const char *flag_name);
19+
void rh_print_flags(void);
20+
21+
#define rh_add_flag(flag_name) \
22+
({ \
23+
static bool __mark_once __read_mostly; \
24+
bool __ret_mark_once = !__mark_once; \
25+
\
26+
if (!__mark_once) \
27+
__mark_once = __rh_add_flag(flag_name); \
28+
unlikely(__ret_mark_once); \
29+
})
30+
#else
31+
void rh_print_flags(void) { };
32+
void rh_add_flag(const char *flag_name) { };
33+
#endif
34+
#endif

kernel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ obj-y = fork.o exec_domain.o panic.o \
1212
notifier.o ksysfs.o cred.o reboot.o \
1313
async.o range.o smpboot.o ucount.o regset.o ksyms_common.o
1414

15-
obj-$(CONFIG_RHEL_DIFFERENCES) += rh_messages.o rh_features.o rh_shadowman.o
15+
obj-$(CONFIG_RHEL_DIFFERENCES) += rh_messages.o rh_flags.o rh_shadowman.o
1616
obj-$(CONFIG_USERMODE_DRIVER) += usermode_driver.o
1717
obj-$(CONFIG_MULTIUSER) += groups.o
1818

kernel/module/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
#define CREATE_TRACE_POINTS
6363
#include <trace/events/module.h>
6464

65-
#include <linux/rh_features.h>
65+
#include <linux/rh_flags.h>
6666

6767
/*
6868
* Mutex protects:
@@ -3397,7 +3397,7 @@ void print_modules(void)
33973397
pr_cont("\n");
33983398

33993399
#ifdef CONFIG_RHEL_DIFFERENCES
3400-
rh_print_used_features();
3400+
rh_print_flags();
34013401
#endif
34023402
}
34033403

kernel/rh_features.c

Lines changed: 0 additions & 116 deletions
This file was deleted.

kernel/rh_flags.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#include <linux/kernel.h>
2+
#include <linux/list.h>
3+
#include <linux/proc_fs.h>
4+
#include <linux/seq_file.h>
5+
#include <linux/slab.h>
6+
#include <linux/spinlock.h>
7+
#include <linux/rh_flags.h>
8+
9+
#define RH_FLAG_NAME_LEN 32
10+
#define MAX_RH_FLAGS 128
11+
#define MAX_RH_FLAG_NAME_LEN (MAX_RH_FLAGS * RH_FLAG_NAME_LEN)
12+
13+
struct rh_flag {
14+
struct list_head list;
15+
char name[RH_FLAG_NAME_LEN];
16+
};
17+
18+
static LIST_HEAD(rh_flag_list);
19+
static DEFINE_SPINLOCK(rh_flag_lock);
20+
21+
bool __rh_add_flag(const char *flag_name)
22+
{
23+
struct rh_flag *feat, *iter;
24+
25+
BUG_ON(in_interrupt());
26+
feat = kzalloc(sizeof(*feat), GFP_ATOMIC);
27+
if (WARN(!feat, "Adding Red Hat flag %s.\n", flag_name))
28+
return false;
29+
strscpy(feat->name, flag_name, RH_FLAG_NAME_LEN);
30+
31+
spin_lock(&rh_flag_lock);
32+
list_for_each_entry_rcu(iter, &rh_flag_list, list) {
33+
if (!strcmp(iter->name, flag_name)) {
34+
kfree(feat);
35+
feat = NULL;
36+
break;
37+
}
38+
}
39+
if (feat)
40+
list_add_rcu(&feat->list, &rh_flag_list);
41+
spin_unlock(&rh_flag_lock);
42+
43+
if (feat)
44+
pr_info("Adding Red Hat flag %s.\n", flag_name);
45+
return true;
46+
}
47+
EXPORT_SYMBOL(__rh_add_flag);
48+
49+
void rh_print_flags(void)
50+
{
51+
struct rh_flag *feat;
52+
53+
/*
54+
* This function cannot do any locking, we're oopsing. Traversing
55+
* rh_flag_list is okay, though, even without the rcu_read_lock
56+
* taken: we never delete from that list and thus don't need the
57+
* delayed free. All we need are the smp barriers invoked by the rcu
58+
* list manipulation routines.
59+
*/
60+
if (list_empty(&rh_flag_list))
61+
return;
62+
printk(KERN_DEFAULT "Red Hat flags:");
63+
list_for_each_entry_lockless(feat, &rh_flag_list, list) {
64+
pr_cont(" %s", feat->name);
65+
}
66+
pr_cont("\n");
67+
}
68+
EXPORT_SYMBOL(rh_print_flags);
69+
70+
#ifdef CONFIG_SYSCTL
71+
static int rh_flags_show(struct ctl_table *ctl, int write,
72+
void __user *buffer, size_t *lenp,
73+
loff_t *ppos)
74+
{
75+
struct ctl_table tbl = { .maxlen = MAX_RH_FLAG_NAME_LEN, };
76+
struct rh_flag *feat;
77+
size_t offs = 0;
78+
int ret;
79+
80+
tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL);
81+
if (!tbl.data)
82+
return -ENOMEM;
83+
((char *)tbl.data)[0] = '\0';
84+
85+
rcu_read_lock();
86+
list_for_each_entry_rcu(feat, &rh_flag_list, list) {
87+
offs += scnprintf(tbl.data + offs, tbl.maxlen - offs, "%s%s",
88+
offs == 0 ? "" : " ", feat->name);
89+
}
90+
rcu_read_unlock();
91+
92+
ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
93+
kfree(tbl.data);
94+
return ret;
95+
}
96+
97+
static struct ctl_table rh_flags_table[] = {
98+
{
99+
.procname = "rh_flags",
100+
.data = &rh_flag_list,
101+
.maxlen = MAX_RH_FLAG_NAME_LEN,
102+
.mode = 0444,
103+
.proc_handler = rh_flags_show,
104+
},
105+
{ }
106+
};
107+
#endif
108+
109+
static __init int rh_flags_init(void)
110+
{
111+
#ifdef CONFIG_SYSCTL
112+
register_sysctl_init("kernel", rh_flags_table);
113+
#endif
114+
return 0;
115+
}
116+
subsys_initcall(rh_flags_init);

0 commit comments

Comments
 (0)