2019-01-09 15:43:29 +03:00
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 Joe Lawrence <joe.lawrence@redhat.com>
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
# include <linux/module.h>
# include <linux/kernel.h>
2020-06-03 21:20:55 +03:00
# include <linux/sched.h>
2019-01-09 15:43:29 +03:00
# include <linux/workqueue.h>
# include <linux/delay.h>
2020-06-03 21:20:55 +03:00
/* load/run-time control from sysfs writer */
static bool block_transition ;
module_param ( block_transition , bool , 0644 ) ;
MODULE_PARM_DESC ( block_transition , " block_transition (default=false) " ) ;
2019-01-09 15:43:29 +03:00
static void busymod_work_func ( struct work_struct * work ) ;
2020-06-03 21:20:55 +03:00
static DECLARE_WORK ( work , busymod_work_func ) ;
2019-01-09 15:43:29 +03:00
static void busymod_work_func ( struct work_struct * work )
{
2020-06-03 21:20:55 +03:00
pr_info ( " %s enter \n " , __func__ ) ;
while ( READ_ONCE ( block_transition ) ) {
/*
* Busy - wait until the sysfs writer has acknowledged a
* blocked transition and clears the flag .
*/
msleep ( 20 ) ;
}
2019-01-09 15:43:29 +03:00
pr_info ( " %s exit \n " , __func__ ) ;
}
static int test_klp_callbacks_busy_init ( void )
{
pr_info ( " %s \n " , __func__ ) ;
2020-06-03 21:20:55 +03:00
schedule_work ( & work ) ;
if ( ! block_transition ) {
/*
* Serialize output : print all messages from the work
* function before returning from init ( ) .
*/
flush_work ( & work ) ;
}
2019-01-09 15:43:29 +03:00
return 0 ;
}
static void test_klp_callbacks_busy_exit ( void )
{
2020-06-03 21:20:55 +03:00
WRITE_ONCE ( block_transition , false ) ;
flush_work ( & work ) ;
2019-01-09 15:43:29 +03:00
pr_info ( " %s \n " , __func__ ) ;
}
module_init ( test_klp_callbacks_busy_init ) ;
module_exit ( test_klp_callbacks_busy_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Joe Lawrence <joe.lawrence@redhat.com> " ) ;
MODULE_DESCRIPTION ( " Livepatch test: busy target module " ) ;