From 91e894ccc77d144e155048c201c2b591a9d66f7d Mon Sep 17 00:00:00 2001
From: jserv
When the The Linux Kernel Module Programming Guide
-4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/platform_device.h>
-7
-8struct devicemodel_data {
-9 char *greeting;
-10 int number;
-11};
-12
-13static int devicemodel_probe(struct platform_device *dev)
-14{
-15 struct devicemodel_data *pd =
-16 (struct devicemodel_data *)(dev->dev.platform_data);
-17
-18 pr_info("devicemodel probe\n");
-19 pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number);
-20
-21 /* Your device initialization code */
-22
-23 return 0;
-24}
-25
-26static int devicemodel_remove(struct platform_device *dev)
-27{
-28 pr_info("devicemodel example removed\n");
-29
-30 /* Your device removal code */
-31
-32 return 0;
-33}
-34
-35static int devicemodel_suspend(struct device *dev)
-36{
-37 pr_info("devicemodel example suspend\n");
-38
-39 /* Your device suspend code */
-40
-41 return 0;
-42}
+7#include <linux/version.h>
+8
+9struct devicemodel_data {
+10 char *greeting;
+11 int number;
+12};
+13
+14static int devicemodel_probe(struct platform_device *dev)
+15{
+16 struct devicemodel_data *pd =
+17 (struct devicemodel_data *)(dev->dev.platform_data);
+18
+19 pr_info("devicemodel probe\n");
+20 pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number);
+21
+22 /* Your device initialization code */
+23
+24 return 0;
+25}
+26#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0)
+27static int devicemodel_remove(struct platform_device *dev)
+28#else
+29static void devicemodel_remove(struct platform_device *dev)
+30#endif
+31{
+32 pr_info("devicemodel example removed\n");
+33
+34 /* Your device removal code */
+35#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0)
+36 return 0;
+37#endif
+38}
+39
+40static int devicemodel_suspend(struct device *dev)
+41{
+42 pr_info("devicemodel example suspend\n");
43
-44static int devicemodel_resume(struct device *dev)
-45{
-46 pr_info("devicemodel example resume\n");
-47
-48 /* Your device resume code */
-49
-50 return 0;
-51}
+44 /* Your device suspend code */
+45
+46 return 0;
+47}
+48
+49static int devicemodel_resume(struct device *dev)
+50{
+51 pr_info("devicemodel example resume\n");
52
-53static const struct dev_pm_ops devicemodel_pm_ops = {
-54 .suspend = devicemodel_suspend,
-55 .resume = devicemodel_resume,
-56 .poweroff = devicemodel_suspend,
-57 .freeze = devicemodel_suspend,
-58 .thaw = devicemodel_resume,
-59 .restore = devicemodel_resume,
-60};
-61
-62static struct platform_driver devicemodel_driver = {
-63 .driver =
-64 {
-65 .name = "devicemodel_example",
-66 .pm = &devicemodel_pm_ops,
-67 },
-68 .probe = devicemodel_probe,
-69 .remove = devicemodel_remove,
-70};
-71
-72static int __init devicemodel_init(void)
-73{
-74 int ret;
-75
-76 pr_info("devicemodel init\n");
-77
-78 ret = platform_driver_register(&devicemodel_driver);
-79
-80 if (ret) {
-81 pr_err("Unable to register driver\n");
-82 return ret;
-83 }
+53 /* Your device resume code */
+54
+55 return 0;
+56}
+57
+58static const struct dev_pm_ops devicemodel_pm_ops = {
+59 .suspend = devicemodel_suspend,
+60 .resume = devicemodel_resume,
+61 .poweroff = devicemodel_suspend,
+62 .freeze = devicemodel_suspend,
+63 .thaw = devicemodel_resume,
+64 .restore = devicemodel_resume,
+65};
+66
+67static struct platform_driver devicemodel_driver = {
+68 .driver =
+69 {
+70 .name = "devicemodel_example",
+71 .pm = &devicemodel_pm_ops,
+72 },
+73 .probe = devicemodel_probe,
+74 .remove = devicemodel_remove,
+75};
+76
+77static int __init devicemodel_init(void)
+78{
+79 int ret;
+80
+81 pr_info("devicemodel init\n");
+82
+83 ret = platform_driver_register(&devicemodel_driver);
84
-85 return 0;
-86}
-87
-88static void __exit devicemodel_exit(void)
-89{
-90 pr_info("devicemodel exit\n");
-91 platform_driver_unregister(&devicemodel_driver);
-92}
-93
-94module_init(devicemodel_init);
-95module_exit(devicemodel_exit);
-96
-97MODULE_LICENSE("GPL");
-98MODULE_DESCRIPTION("Linux Device Model example");
+85 if (ret) {
+86 pr_err("Unable to register driver\n");
+87 return ret;
+88 }
+89
+90 return 0;
+91}
+92
+93static void __exit devicemodel_exit(void)
+94{
+95 pr_info("devicemodel exit\n");
+96 platform_driver_unregister(&devicemodel_driver);
+97}
+98
+99module_init(devicemodel_init);
+100module_exit(devicemodel_exit);
+101
+102MODULE_LICENSE("GPL");
+103MODULE_DESCRIPTION("Linux Device Model example");
18 Optimizations
@@ -6711,10 +6716,10 @@ 1bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);
-2if (unlikely(!bvl)) {
+2if (unlikely(!bvl)) {
3 mempool_free(bio, bio_pool);
4 bio = NULL;
-5 goto out;
+5 goto out;
6}
unlikely
macro is used, the compiler alters its machine instruction output, so that it
@@ -6732,7 +6737,7 @@ 18.2 asm goto
+
asm goto
inline assembly, and the following kernel configurations are set:
@@ -6755,10 +6760,10 @@
-
1pr_info("fastpath 1\n"); -2if (static_branch_unlikely(&fkey)) -3 pr_alert("do unlikely thing\n"); -4pr_info("fastpath 2\n");+
1pr_info("fastpath 1\n"); +2if (static_branch_unlikely(&fkey)) +3 pr_alert("do unlikely thing\n"); +4pr_info("fastpath 2\n");@@ -6771,159 +6776,159 @@
-
1/* -2 * static_key.c -3 */ +1/* +2 * static_key.c +3 */ 4 -5#include <linux/atomic.h> -6#include <linux/device.h> -7#include <linux/fs.h> -8#include <linux/kernel.h> /* for sprintf() */ -9#include <linux/module.h> -10#include <linux/printk.h> -11#include <linux/types.h> -12#include <linux/uaccess.h> /* for get_user and put_user */ -13#include <linux/jump_label.h> /* for static key macros */ -14#include <linux/version.h> +5#include <linux/atomic.h> +6#include <linux/device.h> +7#include <linux/fs.h> +8#include <linux/kernel.h> /* for sprintf() */ +9#include <linux/module.h> +10#include <linux/printk.h> +11#include <linux/types.h> +12#include <linux/uaccess.h> /* for get_user and put_user */ +13#include <linux/jump_label.h> /* for static key macros */ +14#include <linux/version.h> 15 -16#include <asm/errno.h> +16#include <asm/errno.h> 17 -18static int device_open(struct inode *inode, struct file *file); -19static int device_release(struct inode *inode, struct file *file); -20static ssize_t device_read(struct file *file, char __user *buf, size_t count, +18static int device_open(struct inode *inode, struct file *file); +19static int device_release(struct inode *inode, struct file *file); +20static ssize_t device_read(struct file *file, char __user *buf, size_t count, 21 loff_t *ppos); -22static ssize_t device_write(struct file *file, const char __user *buf, -23 size_t count, loff_t *ppos); +22static ssize_t device_write(struct file *file, const char __user *buf, +23 size_t count, loff_t *ppos); 24 -25#define SUCCESS 0 -26#define DEVICE_NAME "key_state" -27#define BUF_LEN 10 +25#define SUCCESS 0 +26#define DEVICE_NAME "key_state" +27#define BUF_LEN 10 28 -29static int major; +29static int major; 30 -31enum { +31enum { 32 CDEV_NOT_USED, 33 CDEV_EXCLUSIVE_OPEN, 34}; 35 -36static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); +36static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); 37 -38static char msg[BUF_LEN + 1]; +38static char msg[BUF_LEN + 1]; 39 -40static struct class *cls; +40static struct class *cls; 41 -42static DEFINE_STATIC_KEY_FALSE(fkey); +42static DEFINE_STATIC_KEY_FALSE(fkey); 43 -44static struct file_operations chardev_fops = { -45#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) +44static struct file_operations chardev_fops = { +45#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) 46 .owner = THIS_MODULE, -47#endif +47#endif 48 .open = device_open, 49 .release = device_release, 50 .read = device_read, 51 .write = device_write, 52}; 53 -54static int __init chardev_init(void) +54static int __init chardev_init(void) 55{ 56 major = register_chrdev(0, DEVICE_NAME, &chardev_fops); -57 if (major < 0) { -58 pr_alert("Registering char device failed with %d\n", major); -59 return major; +57 if (major < 0) { +58 pr_alert("Registering char device failed with %d\n", major); +59 return major; 60 } 61 -62 pr_info("I was assigned major number %d\n", major); +62 pr_info("I was assigned major number %d\n", major); 63 -64#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) +64#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) 65 cls = class_create(THIS_MODULE, DEVICE_NAME); -66#else +66#else 67 cls = class_create(DEVICE_NAME); -68#endif +68#endif 69 70 device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); 71 -72 pr_info("Device created on /dev/%s\n", DEVICE_NAME); +72 pr_info("Device created on /dev/%s\n", DEVICE_NAME); 73 -74 return SUCCESS; +74 return SUCCESS; 75} 76 -77static void __exit chardev_exit(void) +77static void __exit chardev_exit(void) 78{ 79 device_destroy(cls, MKDEV(major, 0)); 80 class_destroy(cls); 81 -82 /* Unregister the device */ +82 /* Unregister the device */ 83 unregister_chrdev(major, DEVICE_NAME); 84} 85 -86/* Methods */ +86/* Methods */ 87 -88/** -89 * Called when a process tried to open the device file, like -90 * cat /dev/key_state -91 */ -92static int device_open(struct inode *inode, struct file *file) +88/** +89 * Called when a process tried to open the device file, like +90 * cat /dev/key_state +91 */ +92static int device_open(struct inode *inode, struct file *file) 93{ -94 if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN)) -95 return -EBUSY; +94 if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN)) +95 return -EBUSY; 96 -97 sprintf(msg, static_key_enabled(&fkey) ? "enabled\n" : "disabled\n"); +97 sprintf(msg, static_key_enabled(&fkey) ? "enabled\n" : "disabled\n"); 98 -99 pr_info("fastpath 1\n"); -100 if (static_branch_unlikely(&fkey)) -101 pr_alert("do unlikely thing\n"); -102 pr_info("fastpath 2\n"); +99 pr_info("fastpath 1\n"); +100 if (static_branch_unlikely(&fkey)) +101 pr_alert("do unlikely thing\n"); +102 pr_info("fastpath 2\n"); 103 104 try_module_get(THIS_MODULE); 105 -106 return SUCCESS; +106 return SUCCESS; 107} 108 -109/** -110 * Called when a process closes the device file -111 */ -112static int device_release(struct inode *inode, struct file *file) +109/** +110 * Called when a process closes the device file +111 */ +112static int device_release(struct inode *inode, struct file *file) 113{ -114 /* We are now ready for our next caller. */ +114 /* We are now ready for our next caller. */ 115 atomic_set(&already_open, CDEV_NOT_USED); 116 -117 /** -118 * Decrement the usage count, or else once you opened the file, you will -119 * never get rid of the module. -120 */ +117 /** +118 * Decrement the usage count, or else once you opened the file, you will +119 * never get rid of the module. +120 */ 121 module_put(THIS_MODULE); 122 -123 return SUCCESS; +123 return SUCCESS; 124} 125 -126/** -127 * Called when a process, which already opened the dev file, attempts to -128 * read from it. -129 */ -130static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ -131 char __user *buffer, /* buffer to fill with data */ -132 size_t length, /* length of the buffer */ +126/** +127 * Called when a process, which already opened the dev file, attempts to +128 * read from it. +129 */ +130static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ +131 char __user *buffer, /* buffer to fill with data */ +132 size_t length, /* length of the buffer */ 133 loff_t *offset) 134{ -135 /* Number of the bytes actually written to the buffer */ -136 int bytes_read = 0; -137 const char *msg_ptr = msg; +135 /* Number of the bytes actually written to the buffer */ +136 int bytes_read = 0; +137 const char *msg_ptr = msg; 138 -139 if (!*(msg_ptr + *offset)) { /* We are at the end of the message */ -140 *offset = 0; /* reset the offset */ -141 return 0; /* signify end of file */ +139 if (!*(msg_ptr + *offset)) { /* We are at the end of the message */ +140 *offset = 0; /* reset the offset */ +141 return 0; /* signify end of file */ 142 } 143 144 msg_ptr += *offset; 145 -146 /* Actually put the data into the buffer */ -147 while (length && *msg_ptr) { -148 /** -149 * The buffer is in the user data segment, not the kernel -150 * segment so "*" assignment won't work. We have to use -151 * put_user which copies data from the kernel data segment to -152 * the user data segment. -153 */ +146 /* Actually put the data into the buffer */ +147 while (length && *msg_ptr) { +148 /** +149 * The buffer is in the user data segment, not the kernel +150 * segment so "*" assignment won't work. We have to use +151 * put_user which copies data from the kernel data segment to +152 * the user data segment. +153 */ 154 put_user(*(msg_ptr++), buffer++); 155 length--; 156 bytes_read++; @@ -6931,41 +6936,41 @@+195MODULE_LICENSE("GPL");18.2 158 159 *offset += bytes_read; 160 -161 /* Most read functions return the number of bytes put into the buffer. */ -162 return bytes_read; +161 /* Most read functions return the number of bytes put into the buffer. */ +162 return bytes_read; 163} 164 -165/* Called when a process writes to dev file; echo "enable" > /dev/key_state */ -166static ssize_t device_write(struct file *filp, const char __user *buffer, -167 size_t length, loff_t *offset) +165/* Called when a process writes to dev file; echo "enable" > /dev/key_state */ +166static ssize_t device_write(struct file *filp, const char __user *buffer, +167 size_t length, loff_t *offset) 168{ -169 char command[10]; +169 char command[10]; 170 -171 if (length > 10) { -172 pr_err("command exceeded 10 char\n"); -173 return -EINVAL; +171 if (length > 10) { +172 pr_err("command exceeded 10 char\n"); +173 return -EINVAL; 174 } 175 -176 if (copy_from_user(command, buffer, length)) -177 return -EFAULT; +176 if (copy_from_user(command, buffer, length)) +177 return -EFAULT; 178 -179 if (strncmp(command, "enable", strlen("enable")) == 0) +179 if (strncmp(command, "enable", strlen("enable")) == 0) 180 static_branch_enable(&fkey); -181 else if (strncmp(command, "disable", strlen("disable")) == 0) +181 else if (strncmp(command, "disable", strlen("disable")) == 0) 182 static_branch_disable(&fkey); -183 else { -184 pr_err("Invalid command: %s\n", command); -185 return -EINVAL; +183 else { +184 pr_err("Invalid command: %s\n", command); +185 return -EINVAL; 186 } 187 -188 /* Again, return the number of input characters used. */ -189 return length; +188 /* Again, return the number of input characters used. */ +189 return length; 190} 191 192module_init(chardev_init); 193module_exit(chardev_exit); 194 -195MODULE_LICENSE("GPL");
To check the state of the static key, we can use the /dev/key_state interface.
diff --git a/lkmpg-for-ht.css b/lkmpg-for-ht.css index 197b0719..792239fc 100644 --- a/lkmpg-for-ht.css +++ b/lkmpg-for-ht.css @@ -4239,31 +4239,31 @@ span#textcolor3549{color:rgb(0,127,0)} span#textcolor3550{color:rgb(0,0,255)} span#textcolor3551{color:rgb(0,127,0)} span#textcolor3552{color:rgb(0,0,255)} -span#textcolor3553{color:rgb(43,145,175)} -span#textcolor3554{color:rgb(43,145,175)} -span#textcolor3555{color:rgb(0,0,255)} +span#textcolor3553{color:rgb(0,127,0)} +span#textcolor3554{color:rgb(0,0,255)} +span#textcolor3555{color:rgb(43,145,175)} span#textcolor3556{color:rgb(43,145,175)} span#textcolor3557{color:rgb(0,0,255)} -span#textcolor3558{color:rgb(0,0,255)} +span#textcolor3558{color:rgb(43,145,175)} span#textcolor3559{color:rgb(0,0,255)} -span#textcolor3560{color:rgb(163,20,20)} -span#textcolor3561{color:rgb(163,20,20)} +span#textcolor3560{color:rgb(0,0,255)} +span#textcolor3561{color:rgb(0,0,255)} span#textcolor3562{color:rgb(163,20,20)} span#textcolor3563{color:rgb(163,20,20)} span#textcolor3564{color:rgb(163,20,20)} span#textcolor3565{color:rgb(163,20,20)} -span#textcolor3566{color:rgb(0,127,0)} -span#textcolor3567{color:rgb(0,0,255)} -span#textcolor3568{color:rgb(0,0,255)} -span#textcolor3569{color:rgb(43,145,175)} +span#textcolor3566{color:rgb(163,20,20)} +span#textcolor3567{color:rgb(163,20,20)} +span#textcolor3568{color:rgb(0,127,0)} +span#textcolor3569{color:rgb(0,0,255)} span#textcolor3570{color:rgb(0,0,255)} -span#textcolor3571{color:rgb(163,20,20)} -span#textcolor3572{color:rgb(163,20,20)} -span#textcolor3573{color:rgb(163,20,20)} -span#textcolor3574{color:rgb(0,127,0)} +span#textcolor3571{color:rgb(0,0,255)} +span#textcolor3572{color:rgb(43,145,175)} +span#textcolor3573{color:rgb(0,0,255)} +span#textcolor3574{color:rgb(0,0,255)} span#textcolor3575{color:rgb(0,0,255)} -span#textcolor3576{color:rgb(0,0,255)} -span#textcolor3577{color:rgb(43,145,175)} +span#textcolor3576{color:rgb(43,145,175)} +span#textcolor3577{color:rgb(0,0,255)} span#textcolor3578{color:rgb(0,0,255)} span#textcolor3579{color:rgb(163,20,20)} span#textcolor3580{color:rgb(163,20,20)} @@ -4271,49 +4271,59 @@ span#textcolor3581{color:rgb(163,20,20)} span#textcolor3582{color:rgb(0,127,0)} span#textcolor3583{color:rgb(0,0,255)} span#textcolor3584{color:rgb(0,0,255)} -span#textcolor3585{color:rgb(43,145,175)} +span#textcolor3585{color:rgb(0,0,255)} span#textcolor3586{color:rgb(0,0,255)} -span#textcolor3587{color:rgb(163,20,20)} -span#textcolor3588{color:rgb(163,20,20)} +span#textcolor3587{color:rgb(43,145,175)} +span#textcolor3588{color:rgb(0,0,255)} span#textcolor3589{color:rgb(163,20,20)} -span#textcolor3590{color:rgb(0,127,0)} -span#textcolor3591{color:rgb(0,0,255)} -span#textcolor3592{color:rgb(0,0,255)} +span#textcolor3590{color:rgb(163,20,20)} +span#textcolor3591{color:rgb(163,20,20)} +span#textcolor3592{color:rgb(0,127,0)} span#textcolor3593{color:rgb(0,0,255)} span#textcolor3594{color:rgb(0,0,255)} -span#textcolor3595{color:rgb(0,0,255)} +span#textcolor3595{color:rgb(43,145,175)} span#textcolor3596{color:rgb(0,0,255)} span#textcolor3597{color:rgb(163,20,20)} -span#textcolor3598{color:rgb(0,0,255)} -span#textcolor3599{color:rgb(43,145,175)} -span#textcolor3600{color:rgb(43,145,175)} -span#textcolor3601{color:rgb(43,145,175)} -span#textcolor3602{color:rgb(163,20,20)} -span#textcolor3603{color:rgb(163,20,20)} -span#textcolor3604{color:rgb(163,20,20)} +span#textcolor3598{color:rgb(163,20,20)} +span#textcolor3599{color:rgb(163,20,20)} +span#textcolor3600{color:rgb(0,127,0)} +span#textcolor3601{color:rgb(0,0,255)} +span#textcolor3602{color:rgb(0,0,255)} +span#textcolor3603{color:rgb(0,0,255)} +span#textcolor3604{color:rgb(0,0,255)} span#textcolor3605{color:rgb(0,0,255)} -span#textcolor3606{color:rgb(163,20,20)} +span#textcolor3606{color:rgb(0,0,255)} span#textcolor3607{color:rgb(163,20,20)} -span#textcolor3608{color:rgb(163,20,20)} -span#textcolor3609{color:rgb(0,0,255)} -span#textcolor3610{color:rgb(0,0,255)} -span#textcolor3611{color:rgb(0,0,255)} -span#textcolor3612{color:rgb(43,145,175)} -span#textcolor3613{color:rgb(43,145,175)} +span#textcolor3608{color:rgb(0,0,255)} +span#textcolor3609{color:rgb(43,145,175)} +span#textcolor3610{color:rgb(43,145,175)} +span#textcolor3611{color:rgb(43,145,175)} +span#textcolor3612{color:rgb(163,20,20)} +span#textcolor3613{color:rgb(163,20,20)} span#textcolor3614{color:rgb(163,20,20)} -span#textcolor3615{color:rgb(163,20,20)} +span#textcolor3615{color:rgb(0,0,255)} span#textcolor3616{color:rgb(163,20,20)} span#textcolor3617{color:rgb(163,20,20)} span#textcolor3618{color:rgb(163,20,20)} +span#textcolor3619{color:rgb(0,0,255)} +span#textcolor3620{color:rgb(0,0,255)} +span#textcolor3621{color:rgb(0,0,255)} +span#textcolor3622{color:rgb(43,145,175)} +span#textcolor3623{color:rgb(43,145,175)} +span#textcolor3624{color:rgb(163,20,20)} +span#textcolor3625{color:rgb(163,20,20)} +span#textcolor3626{color:rgb(163,20,20)} +span#textcolor3627{color:rgb(163,20,20)} +span#textcolor3628{color:rgb(163,20,20)} pre#fancyvrb95{padding:5.69054pt;} pre#fancyvrb95{ border-top: solid 0.4pt; } pre#fancyvrb95{ border-left: solid 0.4pt; } pre#fancyvrb95{ border-bottom: solid 0.4pt; } pre#fancyvrb95{ border-right: solid 0.4pt; } -span#textcolor3619{color:rgb(0,0,255)} -span#textcolor3620{color:rgb(0,0,255)} -span#textcolor3621{color:rgb(0,0,255)} -span#textcolor3622{color:rgb(0,0,255)} +span#textcolor3629{color:rgb(0,0,255)} +span#textcolor3630{color:rgb(0,0,255)} +span#textcolor3631{color:rgb(0,0,255)} +span#textcolor3632{color:rgb(0,0,255)} pre#fancyvrb96{padding:5.69054pt;} pre#fancyvrb96{ border-top: solid 0.4pt; } pre#fancyvrb96{ border-left: solid 0.4pt; } @@ -4329,33 +4339,23 @@ pre#fancyvrb98{ border-top: solid 0.4pt; } pre#fancyvrb98{ border-left: solid 0.4pt; } pre#fancyvrb98{ border-bottom: solid 0.4pt; } pre#fancyvrb98{ border-right: solid 0.4pt; } -span#textcolor3623{color:rgb(163,20,20)} -span#textcolor3624{color:rgb(163,20,20)} -span#textcolor3625{color:rgb(163,20,20)} -span#textcolor3626{color:rgb(0,0,255)} -span#textcolor3627{color:rgb(163,20,20)} -span#textcolor3628{color:rgb(163,20,20)} -span#textcolor3629{color:rgb(163,20,20)} -span#textcolor3630{color:rgb(163,20,20)} -span#textcolor3631{color:rgb(163,20,20)} -span#textcolor3632{color:rgb(163,20,20)} +span#textcolor3633{color:rgb(163,20,20)} +span#textcolor3634{color:rgb(163,20,20)} +span#textcolor3635{color:rgb(163,20,20)} +span#textcolor3636{color:rgb(0,0,255)} +span#textcolor3637{color:rgb(163,20,20)} +span#textcolor3638{color:rgb(163,20,20)} +span#textcolor3639{color:rgb(163,20,20)} +span#textcolor3640{color:rgb(163,20,20)} +span#textcolor3641{color:rgb(163,20,20)} +span#textcolor3642{color:rgb(163,20,20)} pre#fancyvrb99{padding:5.69054pt;} pre#fancyvrb99{ border-top: solid 0.4pt; } pre#fancyvrb99{ border-left: solid 0.4pt; } pre#fancyvrb99{ border-bottom: solid 0.4pt; } pre#fancyvrb99{ border-right: solid 0.4pt; } -span#textcolor3633{color:rgb(0,127,0)} -span#textcolor3634{color:rgb(0,127,0)} -span#textcolor3635{color:rgb(0,127,0)} -span#textcolor3636{color:rgb(0,0,255)} -span#textcolor3637{color:rgb(0,127,0)} -span#textcolor3638{color:rgb(0,0,255)} -span#textcolor3639{color:rgb(0,127,0)} -span#textcolor3640{color:rgb(0,0,255)} -span#textcolor3641{color:rgb(0,127,0)} -span#textcolor3642{color:rgb(0,0,255)} span#textcolor3643{color:rgb(0,127,0)} -span#textcolor3644{color:rgb(0,0,255)} +span#textcolor3644{color:rgb(0,127,0)} span#textcolor3645{color:rgb(0,127,0)} span#textcolor3646{color:rgb(0,0,255)} span#textcolor3647{color:rgb(0,127,0)} @@ -4370,82 +4370,82 @@ span#textcolor3655{color:rgb(0,127,0)} span#textcolor3656{color:rgb(0,0,255)} span#textcolor3657{color:rgb(0,127,0)} span#textcolor3658{color:rgb(0,0,255)} -span#textcolor3659{color:rgb(43,145,175)} +span#textcolor3659{color:rgb(0,127,0)} span#textcolor3660{color:rgb(0,0,255)} -span#textcolor3661{color:rgb(0,0,255)} +span#textcolor3661{color:rgb(0,127,0)} span#textcolor3662{color:rgb(0,0,255)} -span#textcolor3663{color:rgb(43,145,175)} +span#textcolor3663{color:rgb(0,127,0)} span#textcolor3664{color:rgb(0,0,255)} -span#textcolor3665{color:rgb(0,0,255)} +span#textcolor3665{color:rgb(0,127,0)} span#textcolor3666{color:rgb(0,0,255)} -span#textcolor3667{color:rgb(43,145,175)} +span#textcolor3667{color:rgb(0,127,0)} span#textcolor3668{color:rgb(0,0,255)} span#textcolor3669{color:rgb(43,145,175)} -span#textcolor3670{color:rgb(43,145,175)} +span#textcolor3670{color:rgb(0,0,255)} span#textcolor3671{color:rgb(0,0,255)} -span#textcolor3672{color:rgb(43,145,175)} -span#textcolor3673{color:rgb(0,0,255)} +span#textcolor3672{color:rgb(0,0,255)} +span#textcolor3673{color:rgb(43,145,175)} span#textcolor3674{color:rgb(0,0,255)} -span#textcolor3675{color:rgb(43,145,175)} -span#textcolor3676{color:rgb(43,145,175)} -span#textcolor3677{color:rgb(0,0,255)} +span#textcolor3675{color:rgb(0,0,255)} +span#textcolor3676{color:rgb(0,0,255)} +span#textcolor3677{color:rgb(43,145,175)} span#textcolor3678{color:rgb(0,0,255)} -span#textcolor3679{color:rgb(0,0,255)} -span#textcolor3680{color:rgb(0,0,255)} -span#textcolor3681{color:rgb(43,145,175)} -span#textcolor3682{color:rgb(0,0,255)} +span#textcolor3679{color:rgb(43,145,175)} +span#textcolor3680{color:rgb(43,145,175)} +span#textcolor3681{color:rgb(0,0,255)} +span#textcolor3682{color:rgb(43,145,175)} span#textcolor3683{color:rgb(0,0,255)} span#textcolor3684{color:rgb(0,0,255)} span#textcolor3685{color:rgb(43,145,175)} -span#textcolor3686{color:rgb(0,0,255)} +span#textcolor3686{color:rgb(43,145,175)} span#textcolor3687{color:rgb(0,0,255)} span#textcolor3688{color:rgb(0,0,255)} span#textcolor3689{color:rgb(0,0,255)} span#textcolor3690{color:rgb(0,0,255)} -span#textcolor3691{color:rgb(0,0,255)} +span#textcolor3691{color:rgb(43,145,175)} span#textcolor3692{color:rgb(0,0,255)} span#textcolor3693{color:rgb(0,0,255)} -span#textcolor3694{color:rgb(43,145,175)} +span#textcolor3694{color:rgb(0,0,255)} span#textcolor3695{color:rgb(43,145,175)} span#textcolor3696{color:rgb(0,0,255)} -span#textcolor3697{color:rgb(163,20,20)} -span#textcolor3698{color:rgb(163,20,20)} -span#textcolor3699{color:rgb(163,20,20)} +span#textcolor3697{color:rgb(0,0,255)} +span#textcolor3698{color:rgb(0,0,255)} +span#textcolor3699{color:rgb(0,0,255)} span#textcolor3700{color:rgb(0,0,255)} -span#textcolor3701{color:rgb(163,20,20)} -span#textcolor3702{color:rgb(163,20,20)} -span#textcolor3703{color:rgb(163,20,20)} -span#textcolor3704{color:rgb(0,0,255)} -span#textcolor3705{color:rgb(0,0,255)} +span#textcolor3701{color:rgb(0,0,255)} +span#textcolor3702{color:rgb(0,0,255)} +span#textcolor3703{color:rgb(0,0,255)} +span#textcolor3704{color:rgb(43,145,175)} +span#textcolor3705{color:rgb(43,145,175)} span#textcolor3706{color:rgb(0,0,255)} span#textcolor3707{color:rgb(163,20,20)} span#textcolor3708{color:rgb(163,20,20)} span#textcolor3709{color:rgb(163,20,20)} span#textcolor3710{color:rgb(0,0,255)} -span#textcolor3711{color:rgb(0,0,255)} -span#textcolor3712{color:rgb(43,145,175)} -span#textcolor3713{color:rgb(43,145,175)} -span#textcolor3714{color:rgb(0,127,0)} -span#textcolor3715{color:rgb(0,127,0)} -span#textcolor3716{color:rgb(0,127,0)} -span#textcolor3717{color:rgb(0,127,0)} -span#textcolor3718{color:rgb(0,127,0)} -span#textcolor3719{color:rgb(0,127,0)} +span#textcolor3711{color:rgb(163,20,20)} +span#textcolor3712{color:rgb(163,20,20)} +span#textcolor3713{color:rgb(163,20,20)} +span#textcolor3714{color:rgb(0,0,255)} +span#textcolor3715{color:rgb(0,0,255)} +span#textcolor3716{color:rgb(0,0,255)} +span#textcolor3717{color:rgb(163,20,20)} +span#textcolor3718{color:rgb(163,20,20)} +span#textcolor3719{color:rgb(163,20,20)} span#textcolor3720{color:rgb(0,0,255)} -span#textcolor3721{color:rgb(43,145,175)} -span#textcolor3722{color:rgb(0,0,255)} -span#textcolor3723{color:rgb(0,0,255)} -span#textcolor3724{color:rgb(0,0,255)} -span#textcolor3725{color:rgb(0,0,255)} -span#textcolor3726{color:rgb(163,20,20)} -span#textcolor3727{color:rgb(163,20,20)} -span#textcolor3728{color:rgb(163,20,20)} -span#textcolor3729{color:rgb(163,20,20)} -span#textcolor3730{color:rgb(163,20,20)} -span#textcolor3731{color:rgb(163,20,20)} -span#textcolor3732{color:rgb(163,20,20)} -span#textcolor3733{color:rgb(163,20,20)} -span#textcolor3734{color:rgb(163,20,20)} +span#textcolor3721{color:rgb(0,0,255)} +span#textcolor3722{color:rgb(43,145,175)} +span#textcolor3723{color:rgb(43,145,175)} +span#textcolor3724{color:rgb(0,127,0)} +span#textcolor3725{color:rgb(0,127,0)} +span#textcolor3726{color:rgb(0,127,0)} +span#textcolor3727{color:rgb(0,127,0)} +span#textcolor3728{color:rgb(0,127,0)} +span#textcolor3729{color:rgb(0,127,0)} +span#textcolor3730{color:rgb(0,0,255)} +span#textcolor3731{color:rgb(43,145,175)} +span#textcolor3732{color:rgb(0,0,255)} +span#textcolor3733{color:rgb(0,0,255)} +span#textcolor3734{color:rgb(0,0,255)} span#textcolor3735{color:rgb(0,0,255)} span#textcolor3736{color:rgb(163,20,20)} span#textcolor3737{color:rgb(163,20,20)} @@ -4453,81 +4453,91 @@ span#textcolor3738{color:rgb(163,20,20)} span#textcolor3739{color:rgb(163,20,20)} span#textcolor3740{color:rgb(163,20,20)} span#textcolor3741{color:rgb(163,20,20)} -span#textcolor3742{color:rgb(0,0,255)} -span#textcolor3743{color:rgb(0,127,0)} -span#textcolor3744{color:rgb(0,127,0)} -span#textcolor3745{color:rgb(0,127,0)} -span#textcolor3746{color:rgb(0,0,255)} -span#textcolor3747{color:rgb(43,145,175)} -span#textcolor3748{color:rgb(0,0,255)} -span#textcolor3749{color:rgb(0,0,255)} -span#textcolor3750{color:rgb(0,127,0)} -span#textcolor3751{color:rgb(0,127,0)} -span#textcolor3752{color:rgb(0,127,0)} +span#textcolor3742{color:rgb(163,20,20)} +span#textcolor3743{color:rgb(163,20,20)} +span#textcolor3744{color:rgb(163,20,20)} +span#textcolor3745{color:rgb(0,0,255)} +span#textcolor3746{color:rgb(163,20,20)} +span#textcolor3747{color:rgb(163,20,20)} +span#textcolor3748{color:rgb(163,20,20)} +span#textcolor3749{color:rgb(163,20,20)} +span#textcolor3750{color:rgb(163,20,20)} +span#textcolor3751{color:rgb(163,20,20)} +span#textcolor3752{color:rgb(0,0,255)} span#textcolor3753{color:rgb(0,127,0)} span#textcolor3754{color:rgb(0,127,0)} -span#textcolor3755{color:rgb(0,0,255)} -span#textcolor3756{color:rgb(0,127,0)} -span#textcolor3757{color:rgb(0,127,0)} -span#textcolor3758{color:rgb(0,127,0)} -span#textcolor3759{color:rgb(0,127,0)} -span#textcolor3760{color:rgb(0,0,255)} -span#textcolor3761{color:rgb(43,145,175)} -span#textcolor3762{color:rgb(0,0,255)} +span#textcolor3755{color:rgb(0,127,0)} +span#textcolor3756{color:rgb(0,0,255)} +span#textcolor3757{color:rgb(43,145,175)} +span#textcolor3758{color:rgb(0,0,255)} +span#textcolor3759{color:rgb(0,0,255)} +span#textcolor3760{color:rgb(0,127,0)} +span#textcolor3761{color:rgb(0,127,0)} +span#textcolor3762{color:rgb(0,127,0)} span#textcolor3763{color:rgb(0,127,0)} -span#textcolor3764{color:rgb(43,145,175)} -span#textcolor3765{color:rgb(0,127,0)} -span#textcolor3766{color:rgb(43,145,175)} +span#textcolor3764{color:rgb(0,127,0)} +span#textcolor3765{color:rgb(0,0,255)} +span#textcolor3766{color:rgb(0,127,0)} span#textcolor3767{color:rgb(0,127,0)} span#textcolor3768{color:rgb(0,127,0)} -span#textcolor3769{color:rgb(43,145,175)} +span#textcolor3769{color:rgb(0,127,0)} span#textcolor3770{color:rgb(0,0,255)} span#textcolor3771{color:rgb(43,145,175)} span#textcolor3772{color:rgb(0,0,255)} span#textcolor3773{color:rgb(0,127,0)} -span#textcolor3774{color:rgb(0,127,0)} -span#textcolor3775{color:rgb(0,0,255)} -span#textcolor3776{color:rgb(0,127,0)} +span#textcolor3774{color:rgb(43,145,175)} +span#textcolor3775{color:rgb(0,127,0)} +span#textcolor3776{color:rgb(43,145,175)} span#textcolor3777{color:rgb(0,127,0)} -span#textcolor3778{color:rgb(0,0,255)} -span#textcolor3779{color:rgb(0,127,0)} -span#textcolor3780{color:rgb(0,127,0)} -span#textcolor3781{color:rgb(0,127,0)} -span#textcolor3782{color:rgb(0,127,0)} +span#textcolor3778{color:rgb(0,127,0)} +span#textcolor3779{color:rgb(43,145,175)} +span#textcolor3780{color:rgb(0,0,255)} +span#textcolor3781{color:rgb(43,145,175)} +span#textcolor3782{color:rgb(0,0,255)} span#textcolor3783{color:rgb(0,127,0)} span#textcolor3784{color:rgb(0,127,0)} -span#textcolor3785{color:rgb(0,127,0)} -span#textcolor3786{color:rgb(0,0,255)} +span#textcolor3785{color:rgb(0,0,255)} +span#textcolor3786{color:rgb(0,127,0)} span#textcolor3787{color:rgb(0,127,0)} span#textcolor3788{color:rgb(0,0,255)} -span#textcolor3789{color:rgb(43,145,175)} -span#textcolor3790{color:rgb(0,0,255)} -span#textcolor3791{color:rgb(0,0,255)} -span#textcolor3792{color:rgb(43,145,175)} -span#textcolor3793{color:rgb(43,145,175)} -span#textcolor3794{color:rgb(43,145,175)} -span#textcolor3795{color:rgb(0,0,255)} -span#textcolor3796{color:rgb(163,20,20)} -span#textcolor3797{color:rgb(163,20,20)} -span#textcolor3798{color:rgb(163,20,20)} -span#textcolor3799{color:rgb(0,0,255)} +span#textcolor3789{color:rgb(0,127,0)} +span#textcolor3790{color:rgb(0,127,0)} +span#textcolor3791{color:rgb(0,127,0)} +span#textcolor3792{color:rgb(0,127,0)} +span#textcolor3793{color:rgb(0,127,0)} +span#textcolor3794{color:rgb(0,127,0)} +span#textcolor3795{color:rgb(0,127,0)} +span#textcolor3796{color:rgb(0,0,255)} +span#textcolor3797{color:rgb(0,127,0)} +span#textcolor3798{color:rgb(0,0,255)} +span#textcolor3799{color:rgb(43,145,175)} span#textcolor3800{color:rgb(0,0,255)} span#textcolor3801{color:rgb(0,0,255)} -span#textcolor3802{color:rgb(0,0,255)} -span#textcolor3803{color:rgb(163,20,20)} -span#textcolor3804{color:rgb(163,20,20)} +span#textcolor3802{color:rgb(43,145,175)} +span#textcolor3803{color:rgb(43,145,175)} +span#textcolor3804{color:rgb(43,145,175)} span#textcolor3805{color:rgb(0,0,255)} -span#textcolor3806{color:rgb(0,0,255)} +span#textcolor3806{color:rgb(163,20,20)} span#textcolor3807{color:rgb(163,20,20)} span#textcolor3808{color:rgb(163,20,20)} span#textcolor3809{color:rgb(0,0,255)} -span#textcolor3810{color:rgb(163,20,20)} -span#textcolor3811{color:rgb(163,20,20)} -span#textcolor3812{color:rgb(163,20,20)} -span#textcolor3813{color:rgb(0,0,255)} -span#textcolor3814{color:rgb(0,127,0)} +span#textcolor3810{color:rgb(0,0,255)} +span#textcolor3811{color:rgb(0,0,255)} +span#textcolor3812{color:rgb(0,0,255)} +span#textcolor3813{color:rgb(163,20,20)} +span#textcolor3814{color:rgb(163,20,20)} span#textcolor3815{color:rgb(0,0,255)} -span#textcolor3816{color:rgb(163,20,20)} +span#textcolor3816{color:rgb(0,0,255)} +span#textcolor3817{color:rgb(163,20,20)} +span#textcolor3818{color:rgb(163,20,20)} +span#textcolor3819{color:rgb(0,0,255)} +span#textcolor3820{color:rgb(163,20,20)} +span#textcolor3821{color:rgb(163,20,20)} +span#textcolor3822{color:rgb(163,20,20)} +span#textcolor3823{color:rgb(0,0,255)} +span#textcolor3824{color:rgb(0,127,0)} +span#textcolor3825{color:rgb(0,0,255)} +span#textcolor3826{color:rgb(163,20,20)} pre#fancyvrb100{padding:5.69054pt;} pre#fancyvrb100{ border-top: solid 0.4pt; } pre#fancyvrb100{ border-left: solid 0.4pt; } diff --git a/lkmpg-for-ht.html b/lkmpg-for-ht.html index 970470d5..3b5cc95f 100644 --- a/lkmpg-for-ht.html +++ b/lkmpg-for-ht.html @@ -18,7 +18,7 @@
When the unlikely
macro is used, the compiler alters its machine instruction output, so that it
@@ -6732,7 +6737,7 @@
asm goto
inline assembly, and the following kernel configurations are set:
@@ -6755,10 +6760,10 @@
-
1pr_info("fastpath 1\n"); -2if (static_branch_unlikely(&fkey)) -3 pr_alert("do unlikely thing\n"); -4pr_info("fastpath 2\n");+
1pr_info("fastpath 1\n"); +2if (static_branch_unlikely(&fkey)) +3 pr_alert("do unlikely thing\n"); +4pr_info("fastpath 2\n");@@ -6771,159 +6776,159 @@
-
1/* -2 * static_key.c -3 */ +1/* +2 * static_key.c +3 */ 4 -5#include <linux/atomic.h> -6#include <linux/device.h> -7#include <linux/fs.h> -8#include <linux/kernel.h> /* for sprintf() */ -9#include <linux/module.h> -10#include <linux/printk.h> -11#include <linux/types.h> -12#include <linux/uaccess.h> /* for get_user and put_user */ -13#include <linux/jump_label.h> /* for static key macros */ -14#include <linux/version.h> +5#include <linux/atomic.h> +6#include <linux/device.h> +7#include <linux/fs.h> +8#include <linux/kernel.h> /* for sprintf() */ +9#include <linux/module.h> +10#include <linux/printk.h> +11#include <linux/types.h> +12#include <linux/uaccess.h> /* for get_user and put_user */ +13#include <linux/jump_label.h> /* for static key macros */ +14#include <linux/version.h> 15 -16#include <asm/errno.h> +16#include <asm/errno.h> 17 -18static int device_open(struct inode *inode, struct file *file); -19static int device_release(struct inode *inode, struct file *file); -20static ssize_t device_read(struct file *file, char __user *buf, size_t count, +18static int device_open(struct inode *inode, struct file *file); +19static int device_release(struct inode *inode, struct file *file); +20static ssize_t device_read(struct file *file, char __user *buf, size_t count, 21 loff_t *ppos); -22static ssize_t device_write(struct file *file, const char __user *buf, -23 size_t count, loff_t *ppos); +22static ssize_t device_write(struct file *file, const char __user *buf, +23 size_t count, loff_t *ppos); 24 -25#define SUCCESS 0 -26#define DEVICE_NAME "key_state" -27#define BUF_LEN 10 +25#define SUCCESS 0 +26#define DEVICE_NAME "key_state" +27#define BUF_LEN 10 28 -29static int major; +29static int major; 30 -31enum { +31enum { 32 CDEV_NOT_USED, 33 CDEV_EXCLUSIVE_OPEN, 34}; 35 -36static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); +36static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); 37 -38static char msg[BUF_LEN + 1]; +38static char msg[BUF_LEN + 1]; 39 -40static struct class *cls; +40static struct class *cls; 41 -42static DEFINE_STATIC_KEY_FALSE(fkey); +42static DEFINE_STATIC_KEY_FALSE(fkey); 43 -44static struct file_operations chardev_fops = { -45#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) +44static struct file_operations chardev_fops = { +45#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) 46 .owner = THIS_MODULE, -47#endif +47#endif 48 .open = device_open, 49 .release = device_release, 50 .read = device_read, 51 .write = device_write, 52}; 53 -54static int __init chardev_init(void) +54static int __init chardev_init(void) 55{ 56 major = register_chrdev(0, DEVICE_NAME, &chardev_fops); -57 if (major < 0) { -58 pr_alert("Registering char device failed with %d\n", major); -59 return major; +57 if (major < 0) { +58 pr_alert("Registering char device failed with %d\n", major); +59 return major; 60 } 61 -62 pr_info("I was assigned major number %d\n", major); +62 pr_info("I was assigned major number %d\n", major); 63 -64#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) +64#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) 65 cls = class_create(THIS_MODULE, DEVICE_NAME); -66#else +66#else 67 cls = class_create(DEVICE_NAME); -68#endif +68#endif 69 70 device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); 71 -72 pr_info("Device created on /dev/%s\n", DEVICE_NAME); +72 pr_info("Device created on /dev/%s\n", DEVICE_NAME); 73 -74 return SUCCESS; +74 return SUCCESS; 75} 76 -77static void __exit chardev_exit(void) +77static void __exit chardev_exit(void) 78{ 79 device_destroy(cls, MKDEV(major, 0)); 80 class_destroy(cls); 81 -82 /* Unregister the device */ +82 /* Unregister the device */ 83 unregister_chrdev(major, DEVICE_NAME); 84} 85 -86/* Methods */ +86/* Methods */ 87 -88/** -89 * Called when a process tried to open the device file, like -90 * cat /dev/key_state -91 */ -92static int device_open(struct inode *inode, struct file *file) +88/** +89 * Called when a process tried to open the device file, like +90 * cat /dev/key_state +91 */ +92static int device_open(struct inode *inode, struct file *file) 93{ -94 if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN)) -95 return -EBUSY; +94 if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN)) +95 return -EBUSY; 96 -97 sprintf(msg, static_key_enabled(&fkey) ? "enabled\n" : "disabled\n"); +97 sprintf(msg, static_key_enabled(&fkey) ? "enabled\n" : "disabled\n"); 98 -99 pr_info("fastpath 1\n"); -100 if (static_branch_unlikely(&fkey)) -101 pr_alert("do unlikely thing\n"); -102 pr_info("fastpath 2\n"); +99 pr_info("fastpath 1\n"); +100 if (static_branch_unlikely(&fkey)) +101 pr_alert("do unlikely thing\n"); +102 pr_info("fastpath 2\n"); 103 104 try_module_get(THIS_MODULE); 105 -106 return SUCCESS; +106 return SUCCESS; 107} 108 -109/** -110 * Called when a process closes the device file -111 */ -112static int device_release(struct inode *inode, struct file *file) +109/** +110 * Called when a process closes the device file +111 */ +112static int device_release(struct inode *inode, struct file *file) 113{ -114 /* We are now ready for our next caller. */ +114 /* We are now ready for our next caller. */ 115 atomic_set(&already_open, CDEV_NOT_USED); 116 -117 /** -118 * Decrement the usage count, or else once you opened the file, you will -119 * never get rid of the module. -120 */ +117 /** +118 * Decrement the usage count, or else once you opened the file, you will +119 * never get rid of the module. +120 */ 121 module_put(THIS_MODULE); 122 -123 return SUCCESS; +123 return SUCCESS; 124} 125 -126/** -127 * Called when a process, which already opened the dev file, attempts to -128 * read from it. -129 */ -130static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ -131 char __user *buffer, /* buffer to fill with data */ -132 size_t length, /* length of the buffer */ +126/** +127 * Called when a process, which already opened the dev file, attempts to +128 * read from it. +129 */ +130static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ +131 char __user *buffer, /* buffer to fill with data */ +132 size_t length, /* length of the buffer */ 133 loff_t *offset) 134{ -135 /* Number of the bytes actually written to the buffer */ -136 int bytes_read = 0; -137 const char *msg_ptr = msg; +135 /* Number of the bytes actually written to the buffer */ +136 int bytes_read = 0; +137 const char *msg_ptr = msg; 138 -139 if (!*(msg_ptr + *offset)) { /* We are at the end of the message */ -140 *offset = 0; /* reset the offset */ -141 return 0; /* signify end of file */ +139 if (!*(msg_ptr + *offset)) { /* We are at the end of the message */ +140 *offset = 0; /* reset the offset */ +141 return 0; /* signify end of file */ 142 } 143 144 msg_ptr += *offset; 145 -146 /* Actually put the data into the buffer */ -147 while (length && *msg_ptr) { -148 /** -149 * The buffer is in the user data segment, not the kernel -150 * segment so "*" assignment won't work. We have to use -151 * put_user which copies data from the kernel data segment to -152 * the user data segment. -153 */ +146 /* Actually put the data into the buffer */ +147 while (length && *msg_ptr) { +148 /** +149 * The buffer is in the user data segment, not the kernel +150 * segment so "*" assignment won't work. We have to use +151 * put_user which copies data from the kernel data segment to +152 * the user data segment. +153 */ 154 put_user(*(msg_ptr++), buffer++); 155 length--; 156 bytes_read++; @@ -6931,41 +6936,41 @@+195MODULE_LICENSE("GPL");18.2 158 159 *offset += bytes_read; 160 -161 /* Most read functions return the number of bytes put into the buffer. */ -162 return bytes_read; +161 /* Most read functions return the number of bytes put into the buffer. */ +162 return bytes_read; 163} 164 -165/* Called when a process writes to dev file; echo "enable" > /dev/key_state */ -166static ssize_t device_write(struct file *filp, const char __user *buffer, -167 size_t length, loff_t *offset) +165/* Called when a process writes to dev file; echo "enable" > /dev/key_state */ +166static ssize_t device_write(struct file *filp, const char __user *buffer, +167 size_t length, loff_t *offset) 168{ -169 char command[10]; +169 char command[10]; 170 -171 if (length > 10) { -172 pr_err("command exceeded 10 char\n"); -173 return -EINVAL; +171 if (length > 10) { +172 pr_err("command exceeded 10 char\n"); +173 return -EINVAL; 174 } 175 -176 if (copy_from_user(command, buffer, length)) -177 return -EFAULT; +176 if (copy_from_user(command, buffer, length)) +177 return -EFAULT; 178 -179 if (strncmp(command, "enable", strlen("enable")) == 0) +179 if (strncmp(command, "enable", strlen("enable")) == 0) 180 static_branch_enable(&fkey); -181 else if (strncmp(command, "disable", strlen("disable")) == 0) +181 else if (strncmp(command, "disable", strlen("disable")) == 0) 182 static_branch_disable(&fkey); -183 else { -184 pr_err("Invalid command: %s\n", command); -185 return -EINVAL; +183 else { +184 pr_err("Invalid command: %s\n", command); +185 return -EINVAL; 186 } 187 -188 /* Again, return the number of input characters used. */ -189 return length; +188 /* Again, return the number of input characters used. */ +189 return length; 190} 191 192module_init(chardev_init); 193module_exit(chardev_exit); 194 -195MODULE_LICENSE("GPL");
To check the state of the static key, we can use the /dev/key_state interface.