-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sched/spin_lock: rename raw_spin_* to spin_*_notrace #15705
base: master
Are you sure you want to change the base?
Conversation
[Experimental Bot, please feedback here] Yes, this PR appears to meet the NuttX requirements, although it could be improved. Here's a breakdown of why and suggestions for improvement: Strengths:
Weaknesses & Suggestions:
In short: While the core information is present, this PR needs more detail in the Impact and Testing sections to fully meet the NuttX requirements. Be explicit about potential impacts even if you believe them to be minimal, and provide concrete testing evidence. |
…erformance" This reverts commit ace7f0c.
raw_spin in the Linux kernel means disable the preemption before holding the spin lock, not disable trace. Rename raw_spin to spin_*_notrace to make the interface more semantically consistent. Signed-off-by: chao an <[email protected]>
spin_lock -> spin_lock_nopreempt spin_trylock -> spin_trylock_nopreempt spin_unlock -> spin_unlock_nopreempt spin_lock_irqsave -> spin_lock_irqsave_nopreempt spin_trylock_irqsave -> spin_trylock_irqsave_nopreempt spin_unlock_irqrestore -> spin_unlock_irqrestore_nopreempt Signed-off-by: chao an <[email protected]>
…qsave, since it will be called in func spin_lock_irqsave." This reverts commit 8f3a2a6.
…is no need to call it explicitly." This reverts commit b0af946.
This reverts commit 2779989.
…empt flags = spin_lock_irqsave(&g_can_lock); -> flags = spin_lock_irqsave_nopreempt(&g_can_lock); sched_lock(); -> spin_unlock_irqrestore(&g_can_lock, flags); -> sched_unlock(); -> spin_unlock_irqrestore_nopreempt(&g_can_lock, flags); Signed-off-by: chao an <[email protected]>
…ult spin_lock In the RTOS environment, spin_lock is simplified as much as possible to improve performance. At the same time, we provide an set of APIs that disable preemption by default: spin_lock -> spin_lock_nopreempt spin_trylock -> spin_trylock_nopreempt spin_unlock -> spin_unlock_nopreempt spin_lock_irqsave -> spin_lock_irqsave_nopreempt spin_trylock_irqsave -> spin_trylock_irqsave_nopreempt spin_unlock_irqrestore -> spin_unlock_irqrestore_nopreempt This also has the same intention with RT-Linux. Signed-off-by: chao an <[email protected]>
@anchao nice work! Please update our Documentation/ ( https://nuttx.apache.org/docs/latest/implementation/critical_sections.html ) to include these spinlock details! |
spinlock need hold sched lock in no-RT case.
No, RT-Linux map spinlock to mutex. |
@@ -72,9 +72,9 @@ static FAR struct file *files_fget_by_index(FAR struct filelist *list, | |||
FAR struct file *filep; | |||
irqstate_t flags; | |||
|
|||
flags = raw_spin_lock_irqsave(&list->fl_lock); | |||
flags = spin_lock_irqsave(&list->fl_lock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why revert, but not replace raw_spin_lock_irqsave with spin_lock_irqsave_notrace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here need trace, thank you
@@ -278,8 +278,6 @@ spin_lock_nopreempt(FAR volatile spinlock_t *lock) | |||
#ifdef CONFIG_SPINLOCK | |||
static inline_function void spin_lock(FAR volatile spinlock_t *lock) | |||
{ | |||
sched_lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But spinning locks implicitly disable preemption:
https://kernel.googlesource.com/pub/scm/linux/kernel/git/christoph/linux/+/refs/heads/arm64_maxsmp/Documentation/locking/locktypes.rst#76
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use spin_lock_nopreempt() , this PR just restore the code behavior to the same as before
https://docs.kernel.org/locking/locktypes.html contain the detailed information, here is the keypoint: |
why? If no scheduling occurs in the spin_lock protected code, why do we need to hold the sched_lock?
After merge this patch, you can make changes from spin_lock to mutex. This PR just removes sched_lock to improve performance. |
Now we have 4 APIs available to developers 1.spin_lock If you think the code needs to hold sched_lock, please use |
Yes, but you need first change the exuction of ALL IRQ from the interupt context to the thread context. Before that happen, the sched lock must be taken at the same time we hold spinlock.
Let's emphasis the key point:
So, you can't do the change in seperate step without breaking the code:
Let's consider a VERY COMMON case in SMP:
but thread1 is ver hard to know when it can finish the busy wait loop since thread0 is already in the suspend state.
zephyr's k_spin_lock disable irq too, but nuttx's spin_lock doesn't disable irq.
No, the correct semantics(same as Linux) is:
Otherwise, the most code will sufer the random deadlock or long time busy loop like the example I mention previously. Only the special designed code can use spin_lock_preempt/spin_lock_irqsave_preempt as expect. |
Let’s first unify our understanding:
Right?
I can't imagine how many board-level and chip codes will need similar adjustments in the future. Most kernel code does not need to hold sched_lock(), which is unfair to some code that does not cause scheduling. New API semantics should be expressed with new APIs instead of modifying the behavior of the original API.
let remove spin_lock_irqsave() and move the irqsave to spin_lock() ok?
No, keep the current API semantics unchanged, and use new APIs to represent new features |
No, it isn't truth. the critical section is a big lock which is a well known SMP isssue and should be replaced by the fine grant lock step by step:
All known issues are identified and fixed timely(ALL within 24hours), do you have any new issue?
Let's emphasize that the critical section isn't equal to a spin lock since the thread will leave the critical seciton if the thread is suspended by shceduler, but the spinlock doesn't have this capability that's why many places replace enter_critical_section with spin_lock_irqsave + sched_lock.
Where do you find we patch the sched_lock seperatedly? we change to spin_lock_irqsave+sched_lock at the same time.
No, #14578 was created three months ago to fix #9531 and the problem I mentioned before.
that's why spin_lock and raw_spin_lock exist:
But the default version should be the safe one.
Yes, since this place is identified carefully that the lock scheduler sin't really needed.
This is the wrong usage of spinlock which hold the lock in one thread and unlock in another thread.
@hujun260 could we use a new approach to avoid touching esp32 code?
Yes, that's why we provide raw_spin__lock or spin_lock_preempt, but the default one(spin_lock) need to hold sched_lock for safety.
please look at the dissusion: #9531 |
I agree with the changes to the critical section, but the current API changes are beyond my understanding and we are heading down the wrong path.
You have too many mistakes in the entire change cycle. This is just the one point of my review. There are many more, so I won’t share too much.
Let's refrain from unfounded remarks. You intended to replace wo_trace with the raw_ version to avoid the implementation of trace. I pointed out the issues in this approach within PR14943. Nevertheless, you were rather determined to merge the raw_ implementation.
No, let us keep the semantics of spin_lock_irqsave and not extend sched_lock and not follow linux which is an old implementation
who wrong?It is very irresponsible of you to say this. There is nothing wrong with ESP using spin_lock_irqsave. It is your changes that caused the regression. Why do you say it is someone else's fault? It is unreasonable.
stop give the new API, just keep original API semantics
The naming of the API can show the implementation content, which is a perfect naming method. spin_lock_irqsave contains two functions:
Why do you have to make spin_lock_irqsave contain three functions?
|
The current API definition is perfect, and the function name can identify the implementation details of each function.
And your expected API
nuttx is not Linux, please do not introduce the old implementation in Linux into Nuttx |
so, you don't read my reply carefully, let me copy the example again:
but thread1 is ver hard to know when it can finish the busy wait loop since thread0 is already in the suspend state. and the issue @patacongo mention before: #9531 (comment)
same it is unsafe, should be used with the caution.
This behavior isn't Linux specific, ALL OS support spin_lock must disable schedule too, otherwise the deadlock will happen naturally. Please reread the above case again. |
You should use spin_lock_nopreempt() instead of spin_lock()
|
if your code does not enable the interrupt controller and schedler at boot time, why does spin_lock require sched_lock and irq_save? |
I hope you read my reply carefully. Which of the following 2 options do you pick?
or
|
Ok, could you give me an example, when can you use spin_lock API? the interrupt can be happened without your control, which mean spin_lock CAN'T BE CALLED in any thread context. |
The advantage of the first option is that all code does not need to be changed, including the ESP third-party library, and the historical API behavior is the same as before. For the second option, 90% of the places in the kernel that use spin_lock_irqsave need to be replaced with spin_lock_irqsave_preempt, and all implementations that are not in the nuttx repo also need to be re-modified |
if your code does not enable the interrupt controller and schedler at boot time, why does spin_lock require sched_lock and irq_save? bringup phase and ISR and scheduler is not enabled |
There are also some places where more fine-grained control can be used, such as
|
Summary
raw_spin in the Linux kernel means disable the preemption before
holding the spin lock, not disable trace. Rename raw_spin to
spin_*_notrace to make the interface more semantically consistent.
In the RTOS environment, spin_lock is simplified as much as possible to improve performance.
At the same time, we provide an set of APIs that disable preemption by default:
This also has the same intention with RT-Linux.
Signed-off-by: chao an [email protected]
Impact
N/A
Testing
ci-check