Skip to content

Commit df5aa6e

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. strlen() isn't called in a normal case; it's called only when printing the error (sleeping function called from invalid context). Note that Location::file() providing a null-terminated string for better C interoperability is under discussion [1]. Link: rust-lang/libs-team#466 [1] Reviewed-by: Alice Ryhl <aliceryhl@google.com> Co-developed-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
1 parent beeb78d commit df5aa6e

File tree

2 files changed

+36
-21
lines changed

2 files changed

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

+34-21
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 len, int line,
8703+
unsigned int offsets)
87218704
{
87228705
/* Ratelimiting timestamp: */
87238706
static unsigned long prev_jiffy;
@@ -8740,8 +8723,10 @@ 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+
if (len < 0)
8727+
len = strlen(file);
8728+
pr_err("BUG: sleeping function called from invalid context at %.*s:%d\n",
8729+
len, file, line);
87458730
pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n",
87468731
in_atomic(), irqs_disabled(), current->non_block_count,
87478732
current->pid, current->comm);
@@ -8766,8 +8751,36 @@ void __might_resched(const char *file, int line, unsigned int offsets)
87668751
dump_stack();
87678752
add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
87688753
}
8754+
8755+
void __might_resched(const char *file, int line, unsigned int offsets)
8756+
{
8757+
__might_resched_precision(file, -1, line, offsets);
8758+
}
87698759
EXPORT_SYMBOL(__might_resched);
87708760

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

0 commit comments

Comments
 (0)