Skip to content

Commit 2e2feca

Browse files
fujitaJCKeep
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 54fc692 commit 2e2feca

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

include/linux/kernel.h

Lines changed: 2 additions & 0 deletions
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

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8678,24 +8678,6 @@ void __init sched_init(void)
86788678

86798679
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
86808680

8681-
void __might_sleep(const char *file, int line)
8682-
{
8683-
unsigned int state = get_current_state();
8684-
/*
8685-
* Blocking primitives will set (and therefore destroy) current->state,
8686-
* since we will exit with TASK_RUNNING make sure we enter with it,
8687-
* otherwise we will destroy state.
8688-
*/
8689-
WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
8690-
"do not call blocking ops when !TASK_RUNNING; "
8691-
"state=%x set at [<%p>] %pS\n", state,
8692-
(void *)current->task_state_change,
8693-
(void *)current->task_state_change);
8694-
8695-
__might_resched(file, line, 0);
8696-
}
8697-
EXPORT_SYMBOL(__might_sleep);
8698-
86998681
static void print_preempt_disable_ip(int preempt_offset, unsigned long ip)
87008682
{
87018683
if (!IS_ENABLED(CONFIG_DEBUG_PREEMPT))
@@ -8717,7 +8699,8 @@ static inline bool resched_offsets_ok(unsigned int offsets)
87178699
return nested == offsets;
87188700
}
87198701

8720-
void __might_resched(const char *file, int line, unsigned int offsets)
8702+
static void __might_resched_precision(const char *file, int file_len, int line,
8703+
unsigned int offsets)
87218704
{
87228705
/* Ratelimiting timestamp: */
87238706
static unsigned long prev_jiffy;
@@ -8740,8 +8723,8 @@ void __might_resched(const char *file, int line, unsigned int offsets)
87408723
/* Save this before calling printk(), since that will clobber it: */
87418724
preempt_disable_ip = get_preempt_disable_ip(current);
87428725

8743-
pr_err("BUG: sleeping function called from invalid context at %s:%d\n",
8744-
file, line);
8726+
pr_err("BUG: sleeping function called from invalid context at %.*s:%d\n",
8727+
file_len, file, line);
87458728
pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n",
87468729
in_atomic(), irqs_disabled(), current->non_block_count,
87478730
current->pid, current->comm);
@@ -8766,8 +8749,45 @@ void __might_resched(const char *file, int line, unsigned int offsets)
87668749
dump_stack();
87678750
add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
87688751
}
8752+
8753+
/*
8754+
* The precision in vsnprintf() specifies the maximum length of the
8755+
* displayed string. The precision needs to be larger than the actual
8756+
* length of the string, so a sufficiently large value should be used
8757+
* for the filename length.
8758+
*/
8759+
#define MAX_FILENAME_LEN (1<<14)
8760+
8761+
void __might_resched(const char *file, int line, unsigned int offsets)
8762+
{
8763+
__might_resched_precision(file, MAX_FILENAME_LEN, line, offsets);
8764+
}
87698765
EXPORT_SYMBOL(__might_resched);
87708766

8767+
void __might_sleep_precision(const char *file, int len, int line)
8768+
{
8769+
unsigned int state = get_current_state();
8770+
/*
8771+
* Blocking primitives will set (and therefore destroy) current->state,
8772+
* since we will exit with TASK_RUNNING make sure we enter with it,
8773+
* otherwise we will destroy state.
8774+
*/
8775+
WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
8776+
"do not call blocking ops when !TASK_RUNNING; "
8777+
"state=%x set at [<%p>] %pS\n", state,
8778+
(void *)current->task_state_change,
8779+
(void *)current->task_state_change);
8780+
8781+
__might_resched_precision(file, len, line, 0);
8782+
}
8783+
EXPORT_SYMBOL_GPL(__might_sleep_precision);
8784+
8785+
void __might_sleep(const char *file, int line)
8786+
{
8787+
__might_sleep_precision(file, MAX_FILENAME_LEN, line);
8788+
}
8789+
EXPORT_SYMBOL(__might_sleep);
8790+
87718791
void __cant_sleep(const char *file, int line, int preempt_offset)
87728792
{
87738793
static unsigned long prev_jiffy;

0 commit comments

Comments
 (0)