From 91e894ccc77d144e155048c201c2b591a9d66f7d Mon Sep 17 00:00:00 2001 From: jserv Date: Thu, 12 Dec 2024 07:02:55 +0000 Subject: [PATCH] deploy: 3cb12d65a58aae5c6b610f72871c51c1f5c61a9a --- index.html | 413 +++++++++++++++++++++++----------------------- lkmpg-for-ht.css | 342 +++++++++++++++++++------------------- lkmpg-for-ht.html | 413 +++++++++++++++++++++++----------------------- 3 files changed, 594 insertions(+), 574 deletions(-) diff --git a/index.html b/index.html index 970470d5..3b5cc95f 100644 --- a/index.html +++ b/index.html @@ -18,7 +18,7 @@

The Linux Kernel Module Programming Guide

Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang

-
December 11, 2024
+
December 12, 2024
@@ -6596,98 +6596,103 @@

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}

When the 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 @@

18.2

-
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 @@

18.2

-
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 @@ 

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");

+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 @@

The Linux Kernel Module Programming Guide

Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang

-
December 11, 2024
+
December 12, 2024
@@ -6596,98 +6596,103 @@

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}

When the 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 @@

18.2

-
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 @@

18.2

-
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 @@ 

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");

+195MODULE_LICENSE("GPL");

To check the state of the static key, we can use the /dev/key_state interface.