linux kernel: why up() and down() are no longer inlined ?

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
miaowei
Member
Member
Posts: 84
Joined: Wed Dec 18, 2013 9:10 am

linux kernel: why up() and down() are no longer inlined ?

Post by miaowei »

Hi, friends. I am reading the source code of linux 2.4.
In the semaphore partion, its up() and down() operations are implemented as inline functon.

Code: Select all

static inline void down(struct semaphore * sem)
{
	__asm__ __volatile__(
		"# atomic down operation\n\t"
		LOCK "decl %0\n\t"     /* --sem->count */
		"js 2f\n"
		"1:\n"
		".section .text.lock,\"ax\"\n"
		"2:\tcall __down_failed\n\t"
		"jmp 1b\n"
		".previous"
		:"=m" (sem->count)
		:"c" (sem)
		:"memory");
}

static inline void up(struct semaphore * sem)
{
	__asm__ __volatile__(
		"# atomic up operation\n\t"
		LOCK "incl %0\n\t"     /* ++sem->count */
		"jle 2f\n"
		"1:\n"
		".section .text.lock,\"ax\"\n"
		"2:\tcall __up_wakeup\n\t"
		"jmp 1b\n"
		".previous"
		:"=m" (sem->count)
		:"c" (sem)
		:"memory");
}
But in linux 2.6.32, it's no longer inlined.

Code: Select all

void down(struct semaphore *sem)
{
	unsigned long flags;

	spin_lock_irqsave(&sem->lock, flags);
	if (likely(sem->count > 0))
		sem->count--;
	else
		__down(sem);
	spin_unlock_irqrestore(&sem->lock, flags);
}

void up(struct semaphore *sem)
{
	unsigned long flags;

	spin_lock_irqsave(&sem->lock, flags);
	if (likely(list_empty(&sem->wait_list)))
		sem->count++;
	else
		__up(sem);
	spin_unlock_irqrestore(&sem->lock, flags);
}
The code itself is much more graceful, but it's not as fast as linux-2.4 any more.
The inline version works really fast when the code 'fall through', namely, when the down() gets a ticket immediately or up() gives back the tick while no waiters.
The cpu only needs execute a 'lock dec' or 'lock inc' instruction in that case, and that case is more commonly. After all, the race condition doesn't occur very often.

I want to know, what's the reason that made kernel developers can tolerate the overhead of the latter?
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: linux kernel: why up() and down() are no longer inlined

Post by Kevin »

Have a look at this article: https://lwn.net/Articles/273731/

Essentially the reason stated in the commit message for 64ac24e73 is "no longer performance-critical", so the maintainability of a single C function trumps the performance of an assembly function per arch.
Developer of tyndur - community OS of Lowlevel (German)
miaowei
Member
Member
Posts: 84
Joined: Wed Dec 18, 2013 9:10 am

Re: linux kernel: why up() and down() are no longer inlined

Post by miaowei »

Kevin wrote:Have a look at this article: https://lwn.net/Articles/273731/

Essentially the reason stated in the commit message for 64ac24e73 is "no longer performance-critical", so the maintainability of a single C function trumps the performance of an assembly function per arch.
Really Great !
And may i ask you something more ... How did you find this article ? I want to find it by myself the next time i meet a similar question.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: linux kernel: why up() and down() are no longer inlined

Post by Roman »

I think, I'd try digging the git commit history.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: linux kernel: why up() and down() are no longer inlined

Post by Kevin »

miaowei wrote:Really Great !
And may i ask you something more ... How did you find this article ? I want to find it by myself the next time i meet a similar question.
First git grep to find the function you mentioned, then git blame to find out which commit introduced it, and then I just googled for the subject line of that commit (because originally I just wanted to link the commit in some gitweb thing, but then the search turned up the LWN article, which I liked even better).
Developer of tyndur - community OS of Lowlevel (German)
miaowei
Member
Member
Posts: 84
Joined: Wed Dec 18, 2013 9:10 am

Re: linux kernel: why up() and down() are no longer inlined

Post by miaowei »

Thanks !
@Roman @Kevin
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: linux kernel: why up() and down() are no longer inlined

Post by Ycep »

Are they ******** crazy?
If it's no longer performance critical then you need to slow it down?
I hope they returned it back after some time.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: linux kernel: why up() and down() are no longer inlined

Post by Roman »

Functions are often inlined because they reside in hot code paths. As stated, these functions no longer belong to this case.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: linux kernel: why up() and down() are no longer inlined

Post by glauxosdever »

Hi,

Lukand wrote:Are they ******** crazy?
If it's no longer performance critical then you need to slow it down?
I hope they returned it back after some time.
I have to mention that inlining functions makes the total code size bigger.

Besides, would you please stop cursing for no reason?


Regards,
glauxosdever
User avatar
iansjack
Member
Member
Posts: 4688
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: linux kernel: why up() and down() are no longer inlined

Post by iansjack »

glauxosdever wrote:Besides, would you please stop cursing for no reason?
It is certainly worrying that this site allows 11-year olds to post such language. It is inappropriate, on a serious web site, from people of any age let alone young children.
User avatar
Sik
Member
Member
Posts: 251
Joined: Wed Aug 17, 2016 4:55 am

Re: linux kernel: why up() and down() are no longer inlined

Post by Sik »

Um, ignoring the whole manners incident for a moment...
Lukand wrote:If it's no longer performance critical then you need to slow it down?
Maintenance became a bigger issue (especially future maintenance). It was reworked with that new goal in mind. Also the new version is not written in assembly, which makes me think portability was a big factor too.
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: linux kernel: why up() and down() are no longer inlined

Post by Kevin »

Lukand wrote:Are they ******** crazy?
If it's no longer performance critical then you need to slow it down?
I hope they returned it back after some time.
Thanks for writing this, despite the language you used. It gives everyone the clear message that it's best to stay far away from your code as long as you can't even possibly see a point in this decision (the motivation for which was explained both in the LWN article and earlier in this thread), and so it might save some people from using bad code.
Developer of tyndur - community OS of Lowlevel (German)
Post Reply