Skip to content

Commit ac0330c

Browse files
fujitaintel-lab-lkp
authored andcommitted
sched/core: Add __might_sleep_precision()
Add __might_sleep_precision(), Rust friendly version of __might_sleep(), which takes a pointer to a string with the length instead of a null-terminated string. Rust's core::panic::Location::file(), which gives the file name of a caller, doesn't provide a null-terminated string. __might_sleep_precision() uses a precision specifier in the printk format, which specifies the length of a string; a string doesn't need to be a null-terminated. Modify __might_sleep() to call __might_sleep_precision() but the impact should be negligible. When printing the error (sleeping function called from invalid context), the precision string format is used instead of the simple string format; the precision specifies the the maximum length of the displayed string. Note that Location::file() providing a null-terminated string for better C interoperability is under discussion [1]. [1]: rust-lang/libs-team#466 Tested-by: Daniel Almeida <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Co-developed-by: Boqun Feng <[email protected]> Signed-off-by: Boqun Feng <[email protected]> Signed-off-by: FUJITA Tomonori <[email protected]>
1 parent f4d2ef4 commit ac0330c

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

include/linux/kernel.h

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ extern int dynamic_might_resched(void);
8787
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
8888
extern void __might_resched(const char *file, int line, unsigned int offsets);
8989
extern void __might_sleep(const char *file, int line);
90+
extern void __might_sleep_precision(const char *file, int len, int line);
9091
extern void __cant_sleep(const char *file, int line, int preempt_offset);
9192
extern void __cant_migrate(const char *file, int line);
9293

@@ -145,6 +146,7 @@ extern void __cant_migrate(const char *file, int line);
145146
static inline void __might_resched(const char *file, int line,
146147
unsigned int offsets) { }
147148
static inline void __might_sleep(const char *file, int line) { }
149+
static inline void __might_sleep_precision(const char *file, int len, int line) { }
148150
# define might_sleep() do { might_resched(); } while (0)
149151
# define cant_sleep() do { } while (0)
150152
# define cant_migrate() do { } while (0)

kernel/sched/core.c

+41-21
Original file line numberDiff line numberDiff line change
@@ -8730,24 +8730,6 @@ void __init sched_init(void)
87308730

87318731
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
87328732

8733-
void __might_sleep(const char *file, int line)
8734-
{
8735-
unsigned int state = get_current_state();
8736-
/*
8737-
* Blocking primitives will set (and therefore destroy) current->state,
8738-
* since we will exit with TASK_RUNNING make sure we enter with it,
8739-
* otherwise we will destroy state.
8740-
*/
8741-
WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
8742-
"do not call blocking ops when !TASK_RUNNING; "
8743-
"state=%x set at [<%p>] %pS\n", state,
8744-
(void *)current->task_state_change,
8745-
(void *)current->task_state_change);
8746-
8747-
__might_resched(file, line, 0);
8748-
}
8749-
EXPORT_SYMBOL(__might_sleep);
8750-
87518733
static void print_preempt_disable_ip(int preempt_offset, unsigned long ip)
87528734
{
87538735
if (!IS_ENABLED(CONFIG_DEBUG_PREEMPT))
@@ -8769,7 +8751,8 @@ static inline bool resched_offsets_ok(unsigned int offsets)
87698751
return nested == offsets;
87708752
}
87718753

8772-
void __might_resched(const char *file, int line, unsigned int offsets)
8754+
static void __might_resched_precision(const char *file, int file_len, int line,
8755+
unsigned int offsets)
87738756
{
87748757
/* Ratelimiting timestamp: */
87758758
static unsigned long prev_jiffy;
@@ -8792,8 +8775,8 @@ void __might_resched(const char *file, int line, unsigned int offsets)
87928775
/* Save this before calling printk(), since that will clobber it: */
87938776
preempt_disable_ip = get_preempt_disable_ip(current);
87948777

8795-
pr_err("BUG: sleeping function called from invalid context at %s:%d\n",
8796-
file, line);
8778+
pr_err("BUG: sleeping function called from invalid context at %.*s:%d\n",
8779+
file_len, file, line);
87978780
pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n",
87988781
in_atomic(), irqs_disabled(), current->non_block_count,
87998782
current->pid, current->comm);
@@ -8818,8 +8801,45 @@ void __might_resched(const char *file, int line, unsigned int offsets)
88188801
dump_stack();
88198802
add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
88208803
}
8804+
8805+
/*
8806+
* The precision in vsnprintf() specifies the maximum length of the
8807+
* displayed string. The precision needs to be larger than the actual
8808+
* length of the string, so a sufficiently large value should be used
8809+
* for the filename length.
8810+
*/
8811+
#define MAX_FILENAME_LEN (1<<14)
8812+
8813+
void __might_resched(const char *file, int line, unsigned int offsets)
8814+
{
8815+
__might_resched_precision(file, MAX_FILENAME_LEN, line, offsets);
8816+
}
88218817
EXPORT_SYMBOL(__might_resched);
88228818

8819+
void __might_sleep_precision(const char *file, int len, int line)
8820+
{
8821+
unsigned int state = get_current_state();
8822+
/*
8823+
* Blocking primitives will set (and therefore destroy) current->state,
8824+
* since we will exit with TASK_RUNNING make sure we enter with it,
8825+
* otherwise we will destroy state.
8826+
*/
8827+
WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
8828+
"do not call blocking ops when !TASK_RUNNING; "
8829+
"state=%x set at [<%p>] %pS\n", state,
8830+
(void *)current->task_state_change,
8831+
(void *)current->task_state_change);
8832+
8833+
__might_resched_precision(file, len, line, 0);
8834+
}
8835+
EXPORT_SYMBOL_GPL(__might_sleep_precision);
8836+
8837+
void __might_sleep(const char *file, int line)
8838+
{
8839+
__might_sleep_precision(file, MAX_FILENAME_LEN, line);
8840+
}
8841+
EXPORT_SYMBOL(__might_sleep);
8842+
88238843
void __cant_sleep(const char *file, int line, int preempt_offset)
88248844
{
88258845
static unsigned long prev_jiffy;

0 commit comments

Comments
 (0)