I think that's because SLQB
doesn't pass through big object allocation to page allocator.
netperf UDP-U-1k has less improvement with SLQB.
That sounds like just the page allocator needs to be improved.
That would help everyone. We talked a bit about this earlier,
some of the heuristics for hot/cold pages are quite outdated
and have been tuned for obsolete machines and also its fast path
is quite long. Unfortunately no code currently.
-Andi
--
ak@linux.intel.com -- Speaking for myself only.
On Fri, 2009-01-16 at 11:20 +0100, Andi Kleen wrote:
"Zhang, Yanmin" [off-list ref] writes:
quoted
I think that's because SLQB
doesn't pass through big object allocation to page allocator.
netperf UDP-U-1k has less improvement with SLQB.
That sounds like just the page allocator needs to be improved.
That would help everyone. We talked a bit about this earlier,
some of the heuristics for hot/cold pages are quite outdated
and have been tuned for obsolete machines and also its fast path
is quite long. Unfortunately no code currently.
Andi,
Thanks for your kind information. I did more investigation with SLUB
on netperf UDP-U-4k issue.
oprofile shows:
328058 30.1342 linux-2.6.29-rc2 copy_user_generic_string
134666 12.3699 linux-2.6.29-rc2 __free_pages_ok
125447 11.5231 linux-2.6.29-rc2 get_page_from_freelist
22611 2.0770 linux-2.6.29-rc2 __sk_mem_reclaim
21442 1.9696 linux-2.6.29-rc2 list_del
21187 1.9462 linux-2.6.29-rc2 __ip_route_output_key
So __free_pages_ok and get_page_from_freelist consume too much cpu time.
With SLQB, these 2 functions almost don't consume time.
Command 'slabinfo -AD' shows:
Name Objects Alloc Free %Fast
:0000256 1685 29611065 29609548 99 99
:0000168 2987 164689 161859 94 39
:0004096 1471 114918 113490 99 97
So kmem_cache :0000256 is very active.
Kernel stack dump in __free_pages_ok shows
[<ffffffff8027010f>] __free_pages_ok+0x109/0x2e0
[<ffffffff8024bb34>] autoremove_wake_function+0x0/0x2e
[<ffffffff8060f387>] __kfree_skb+0x9/0x6f
[<ffffffff8061204b>] skb_free_datagram+0xc/0x31
[<ffffffff8064b528>] udp_recvmsg+0x1e7/0x26f
[<ffffffff8060b509>] sock_common_recvmsg+0x30/0x45
[<ffffffff80609acd>] sock_recvmsg+0xd5/0xed
The callchain is:
__kfree_skb =>
kfree_skbmem =>
kmem_cache_free(skbuff_head_cache, skb);
kmem_cache skbuff_head_cache's object size is just 256, so it shares the kmem_cache
with :0000256. Their order is 1 which means every slab consists of 2 physical pages.
netperf UDP-U-4k is a UDP stream testing. client process keeps sending 4k-size packets
to server process and server process just receives the packets one by one.
If we start CPU_NUM clients and the same number of servers, every client will send lots
of packets within one sched slice, then process scheduler schedules the server to receive
many packets within one sched slice; then client resends again. So there are many packets
in the queue. When server receive the packets, it frees skbuff_head_cache. When the slab's
objects are all free, the slab will be released by calling __free_pages. Such batch
sending/receiving creates lots of slab free activity.
Page allocator has an array at zone_pcp(zone, cpu)->pcp to keep a page buffer for page order 0.
But here skbuff_head_cache's order is 1, so UDP-U-4k couldn't benefit from the page buffer.
SLQB has no such issue, because:
1) SLQB has a percpu freelist. Free objects are put to the list firstly and can be picked up
later on quickly without lock. A batch parameter to control the free object recollection is mostly
1024.
2) SLQB slab order mostly is 0, so although sometimes it calls alloc_pages/free_pages, it can
benefit from zone_pcp(zone, cpu)->pcp page buffer.
So SLUB need resolve such issues that one process allocates a batch of objects and another process
frees them batchly.
yanmin
From: Christoph Lameter <hidden> Date: 2009-01-22 00:31:50
On Tue, 20 Jan 2009, Zhang, Yanmin wrote:
kmem_cache skbuff_head_cache's object size is just 256, so it shares the kmem_cache
with :0000256. Their order is 1 which means every slab consists of 2 physical pages.
That order can be changed. Try specifying slub_max_order=0 on the kernel
command line to force an order 0 alloc.
The queues of the page allocator are of limited use due to their overhead.
Order-1 allocations can actually be 5% faster than order-0. order-0 makes
sense if pages are pushed rapidly to the page allocator and are then
reissues elsewhere. If there is a linear consumption then the page
allocator queues are just overhead.
Page allocator has an array at zone_pcp(zone, cpu)->pcp to keep a page buffer for page order 0.
But here skbuff_head_cache's order is 1, so UDP-U-4k couldn't benefit from the page buffer.
That usually does not matter because of partial list avoiding page
allocator actions.
SLQB has no such issue, because:
1) SLQB has a percpu freelist. Free objects are put to the list firstly and can be picked up
later on quickly without lock. A batch parameter to control the free object recollection is mostly
1024.
2) SLQB slab order mostly is 0, so although sometimes it calls alloc_pages/free_pages, it can
benefit from zone_pcp(zone, cpu)->pcp page buffer.
So SLUB need resolve such issues that one process allocates a batch of objects and another process
frees them batchly.
SLUB has a percpu freelist but its bounded by the basic allocation unit.
You can increase that by modifying the allocation order. Writing a 3 or 5
into the order value in /sys/kernel/slab/xxx/order would do the trick.
On Wed, 2009-01-21 at 18:58 -0500, Christoph Lameter wrote:
On Tue, 20 Jan 2009, Zhang, Yanmin wrote:
quoted
kmem_cache skbuff_head_cache's object size is just 256, so it shares the kmem_cache
with :0000256. Their order is 1 which means every slab consists of 2 physical pages.
That order can be changed. Try specifying slub_max_order=0 on the kernel
command line to force an order 0 alloc.
I tried slub_max_order=0 and there is no improvement on this UDP-U-4k issue.
Both get_page_from_freelist and __free_pages_ok's cpu time are still very high.
I checked my instrumentation in kernel and found it's caused by large object allocation/free
whose size is more than PAGE_SIZE. Here its order is 1.
The right free callchain is __kfree_skb => skb_release_all => skb_release_data.
So this case isn't the issue that batch of allocation/free might erase partial page
functionality.
'#slaninfo -AD' couldn't show statistics of large object allocation/free. Can we add
such info? That will be more helpful.
In addition, I didn't find such issue wih TCP stream testing.
The queues of the page allocator are of limited use due to their overhead.
Order-1 allocations can actually be 5% faster than order-0. order-0 makes
sense if pages are pushed rapidly to the page allocator and are then
reissues elsewhere. If there is a linear consumption then the page
allocator queues are just overhead.
quoted
Page allocator has an array at zone_pcp(zone, cpu)->pcp to keep a page buffer for page order 0.
But here skbuff_head_cache's order is 1, so UDP-U-4k couldn't benefit from the page buffer.
That usually does not matter because of partial list avoiding page
allocator actions.
quoted
SLQB has no such issue, because:
1) SLQB has a percpu freelist. Free objects are put to the list firstly and can be picked up
later on quickly without lock. A batch parameter to control the free object recollection is mostly
1024.
2) SLQB slab order mostly is 0, so although sometimes it calls alloc_pages/free_pages, it can
benefit from zone_pcp(zone, cpu)->pcp page buffer.
So SLUB need resolve such issues that one process allocates a batch of objects and another process
frees them batchly.
SLUB has a percpu freelist but its bounded by the basic allocation unit.
You can increase that by modifying the allocation order. Writing a 3 or 5
into the order value in /sys/kernel/slab/xxx/order would do the trick.
From: Pekka Enberg <hidden> Date: 2009-01-22 09:16:13
On Thu, 2009-01-22 at 16:36 +0800, Zhang, Yanmin wrote:
On Wed, 2009-01-21 at 18:58 -0500, Christoph Lameter wrote:
quoted
On Tue, 20 Jan 2009, Zhang, Yanmin wrote:
quoted
kmem_cache skbuff_head_cache's object size is just 256, so it shares the kmem_cache
with :0000256. Their order is 1 which means every slab consists of 2 physical pages.
That order can be changed. Try specifying slub_max_order=0 on the kernel
command line to force an order 0 alloc.
I tried slub_max_order=0 and there is no improvement on this UDP-U-4k issue.
Both get_page_from_freelist and __free_pages_ok's cpu time are still very high.
I checked my instrumentation in kernel and found it's caused by large object allocation/free
whose size is more than PAGE_SIZE. Here its order is 1.
The right free callchain is __kfree_skb => skb_release_all => skb_release_data.
So this case isn't the issue that batch of allocation/free might erase partial page
functionality.
So is this the kfree(skb->head) in skb_release_data() or the put_page()
calls in the same function in a loop?
If it's the former, with big enough size passed to __alloc_skb(), the
networking code might be taking a hit from the SLUB page allocator
pass-through.
Pekka
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, 2009-01-22 at 11:15 +0200, Pekka Enberg wrote:
On Thu, 2009-01-22 at 16:36 +0800, Zhang, Yanmin wrote:
quoted
On Wed, 2009-01-21 at 18:58 -0500, Christoph Lameter wrote:
quoted
On Tue, 20 Jan 2009, Zhang, Yanmin wrote:
quoted
kmem_cache skbuff_head_cache's object size is just 256, so it shares the kmem_cache
with :0000256. Their order is 1 which means every slab consists of 2 physical pages.
That order can be changed. Try specifying slub_max_order=0 on the kernel
command line to force an order 0 alloc.
I tried slub_max_order=0 and there is no improvement on this UDP-U-4k issue.
Both get_page_from_freelist and __free_pages_ok's cpu time are still very high.
I checked my instrumentation in kernel and found it's caused by large object allocation/free
whose size is more than PAGE_SIZE. Here its order is 1.
The right free callchain is __kfree_skb => skb_release_all => skb_release_data.
So this case isn't the issue that batch of allocation/free might erase partial page
functionality.
So is this the kfree(skb->head) in skb_release_data() or the put_page()
calls in the same function in a loop?
It's kfree(skb->head).
If it's the former, with big enough size passed to __alloc_skb(), the
networking code might be taking a hit from the SLUB page allocator
pass-through.
From: Pekka Enberg <hidden> Date: 2009-01-22 09:48:17
On Thu, 2009-01-22 at 17:28 +0800, Zhang, Yanmin wrote:
On Thu, 2009-01-22 at 11:15 +0200, Pekka Enberg wrote:
quoted
On Thu, 2009-01-22 at 16:36 +0800, Zhang, Yanmin wrote:
quoted
On Wed, 2009-01-21 at 18:58 -0500, Christoph Lameter wrote:
quoted
On Tue, 20 Jan 2009, Zhang, Yanmin wrote:
quoted
kmem_cache skbuff_head_cache's object size is just 256, so it shares the kmem_cache
with :0000256. Their order is 1 which means every slab consists of 2 physical pages.
That order can be changed. Try specifying slub_max_order=0 on the kernel
command line to force an order 0 alloc.
I tried slub_max_order=0 and there is no improvement on this UDP-U-4k issue.
Both get_page_from_freelist and __free_pages_ok's cpu time are still very high.
I checked my instrumentation in kernel and found it's caused by large object allocation/free
whose size is more than PAGE_SIZE. Here its order is 1.
The right free callchain is __kfree_skb => skb_release_all => skb_release_data.
So this case isn't the issue that batch of allocation/free might erase partial page
functionality.
So is this the kfree(skb->head) in skb_release_data() or the put_page()
calls in the same function in a loop?
It's kfree(skb->head).
quoted
If it's the former, with big enough size passed to __alloc_skb(), the
networking code might be taking a hit from the SLUB page allocator
pass-through.
Do we know what kind of size is being passed to __alloc_skb() in this
case? Maybe we want to do something like this.
Pekka
SLUB: revert page allocator pass-through
This is a revert of commit aadb4bc4a1f9108c1d0fbd121827c936c2ed4217 ("SLUB:
direct pass through of page size or higher kmalloc requests").
---
@@ -3022,7 +3006,7 @@ void __init kmem_cache_init(void)slab_state=UP;/* Provide the correct kmalloc names now that the caches are up */-for(i=KMALLOC_SHIFT_LOW;i<=PAGE_SHIFT;i++)+for(i=KMALLOC_SHIFT_LOW;i<=KMALLOC_SHIFT_HIGH;i++)kmalloc_caches[i].name=kasprintf(GFP_KERNEL,"kmalloc-%d",1<<i);
On Thu, 2009-01-22 at 11:47 +0200, Pekka Enberg wrote:
On Thu, 2009-01-22 at 17:28 +0800, Zhang, Yanmin wrote:
quoted
On Thu, 2009-01-22 at 11:15 +0200, Pekka Enberg wrote:
quoted
On Thu, 2009-01-22 at 16:36 +0800, Zhang, Yanmin wrote:
quoted
On Wed, 2009-01-21 at 18:58 -0500, Christoph Lameter wrote:
quoted
On Tue, 20 Jan 2009, Zhang, Yanmin wrote:
quoted
kmem_cache skbuff_head_cache's object size is just 256, so it shares the kmem_cache
with :0000256. Their order is 1 which means every slab consists of 2 physical pages.
That order can be changed. Try specifying slub_max_order=0 on the kernel
command line to force an order 0 alloc.
I tried slub_max_order=0 and there is no improvement on this UDP-U-4k issue.
Both get_page_from_freelist and __free_pages_ok's cpu time are still very high.
I checked my instrumentation in kernel and found it's caused by large object allocation/free
whose size is more than PAGE_SIZE. Here its order is 1.
The right free callchain is __kfree_skb => skb_release_all => skb_release_data.
So this case isn't the issue that batch of allocation/free might erase partial page
functionality.
So is this the kfree(skb->head) in skb_release_data() or the put_page()
calls in the same function in a loop?
It's kfree(skb->head).
quoted
If it's the former, with big enough size passed to __alloc_skb(), the
networking code might be taking a hit from the SLUB page allocator
pass-through.
Do we know what kind of size is being passed to __alloc_skb() in this
case?
In function __alloc_skb, original parameter size=4155,
SKB_DATA_ALIGN(size)=4224, sizeof(struct skb_shared_info)=472, so
__kmalloc_track_caller's parameter size=4696.
Maybe we want to do something like this.
Pekka
SLUB: revert page allocator pass-through
This patch amost fixes the netperf UDP-U-4k issue.
#slabinfo -AD
Name Objects Alloc Free %Fast
:0000256 1658 70350463 70348946 99 99
kmalloc-8192 31 70322309 70322293 99 99
:0000168 2592 143154 140684 93 28
:0004096 1456 91072 89644 99 96
:0000192 3402 63838 60491 89 11
:0000064 6177 49635 43743 98 77
So kmalloc-8192 appears. Without the patch, kmalloc-8192 hides.
kmalloc-8192's default order on my 8-core stoakley is 2.
1) If I start CPU_NUM clients and servers, SLUB's result is about 2% better than SLQB's;
2) If I start 1 clinet and 1 server, and bind them to different physical cpu, SLQB's result
is about 10% better than SLUB's.
I don't know why there is still 10% difference with item 2). Maybe cachemiss causes it?
quoted hunk
This is a revert of commit aadb4bc4a1f9108c1d0fbd121827c936c2ed4217 ("SLUB:
direct pass through of page size or higher kmalloc requests").
---
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Pekka Enberg <hidden> Date: 2009-01-23 06:56:57
Zhang, Yanmin wrote:
quoted
quoted
quoted
If it's the former, with big enough size passed to __alloc_skb(), the
networking code might be taking a hit from the SLUB page allocator
pass-through.
Do we know what kind of size is being passed to __alloc_skb() in this
case?
In function __alloc_skb, original parameter size=4155,
SKB_DATA_ALIGN(size)=4224, sizeof(struct skb_shared_info)=472, so
__kmalloc_track_caller's parameter size=4696.
OK, so all allocations go straight to the page allocator.
quoted
Maybe we want to do something like this.
SLUB: revert page allocator pass-through
This patch amost fixes the netperf UDP-U-4k issue.
#slabinfo -AD
Name Objects Alloc Free %Fast
:0000256 1658 70350463 70348946 99 99
kmalloc-8192 31 70322309 70322293 99 99
:0000168 2592 143154 140684 93 28
:0004096 1456 91072 89644 99 96
:0000192 3402 63838 60491 89 11
:0000064 6177 49635 43743 98 77
So kmalloc-8192 appears. Without the patch, kmalloc-8192 hides.
kmalloc-8192's default order on my 8-core stoakley is 2.
Christoph, should we merge my patch as-is or do you have an alternative
fix in mind? We could, of course, increase kmalloc() caches one level up
to 8192 or higher.
1) If I start CPU_NUM clients and servers, SLUB's result is about 2% better than SLQB's;
2) If I start 1 clinet and 1 server, and bind them to different physical cpu, SLQB's result
is about 10% better than SLUB's.
I don't know why there is still 10% difference with item 2). Maybe cachemiss causes it?
Maybe we can use the perfstat and/or kerneltop utilities of the new perf
counters patch to diagnose this:
http://lkml.org/lkml/2009/1/21/273
And do oprofile, of course. Thanks!
Pekka
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Pekka Enberg <hidden> Date: 2009-01-23 08:06:56
On Fri, 2009-01-23 at 08:52 +0200, Pekka Enberg wrote:
quoted
1) If I start CPU_NUM clients and servers, SLUB's result is about 2% better than SLQB's;
2) If I start 1 clinet and 1 server, and bind them to different physical cpu, SLQB's result
is about 10% better than SLUB's.
I don't know why there is still 10% difference with item 2). Maybe cachemiss causes it?
Maybe we can use the perfstat and/or kerneltop utilities of the new perf
counters patch to diagnose this:
http://lkml.org/lkml/2009/1/21/273
And do oprofile, of course. Thanks!
I assume binding the client and the server to different physical CPUs
also means that the SKB is always allocated on CPU 1 and freed on CPU
2? If so, we will be taking the __slab_free() slow path all the time on
kfree() which will cause cache effects, no doubt.
But there's another potential performance hit we're taking because the
object size of the cache is so big. As allocations from CPU 1 keep
coming in, we need to allocate new pages and unfreeze the per-cpu page.
That in turn causes __slab_free() to be more eager to discard the slab
(see the PageSlubFrozen check there).
So before going for cache profiling, I'd really like to see an oprofile
report. I suspect we're still going to see much more page allocator
activity there than with SLAB or SLQB which is why we're still behaving
so badly here.
Pekka
On Fri, 2009-01-23 at 10:06 +0200, Pekka Enberg wrote:
On Fri, 2009-01-23 at 08:52 +0200, Pekka Enberg wrote:
quoted
quoted
1) If I start CPU_NUM clients and servers, SLUB's result is about 2% better than SLQB's;
2) If I start 1 clinet and 1 server, and bind them to different physical cpu, SLQB's result
is about 10% better than SLUB's.
I don't know why there is still 10% difference with item 2). Maybe cachemiss causes it?
Maybe we can use the perfstat and/or kerneltop utilities of the new perf
counters patch to diagnose this:
http://lkml.org/lkml/2009/1/21/273
And do oprofile, of course. Thanks!
I assume binding the client and the server to different physical CPUs
also means that the SKB is always allocated on CPU 1 and freed on CPU
2? If so, we will be taking the __slab_free() slow path all the time on
kfree() which will cause cache effects, no doubt.
But there's another potential performance hit we're taking because the
object size of the cache is so big. As allocations from CPU 1 keep
coming in, we need to allocate new pages and unfreeze the per-cpu page.
That in turn causes __slab_free() to be more eager to discard the slab
(see the PageSlubFrozen check there).
So before going for cache profiling, I'd really like to see an oprofile
report. I suspect we're still going to see much more page allocator
activity
Theoretically, it should, but oprofile doesn't show that.
there than with SLAB or SLQB which is why we're still behaving
so badly here.
oprofile output with 2.6.29-rc2-slubrevertlarge:
CPU: Core 2, speed 2666.71 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
samples % app name symbol name
132779 32.9951 vmlinux copy_user_generic_string
25334 6.2954 vmlinux schedule
21032 5.2264 vmlinux tg_shares_up
17175 4.2679 vmlinux __skb_recv_datagram
9091 2.2591 vmlinux sock_def_readable
8934 2.2201 vmlinux mwait_idle
8796 2.1858 vmlinux try_to_wake_up
6940 1.7246 vmlinux __slab_free
#slaninfo -AD
Name Objects Alloc Free %Fast
:0000256 1643 5215544 5214027 94 0
kmalloc-8192 28 5189576 5189560 0 0
:0000168 2631 141466 138976 92 28
:0004096 1452 88697 87269 99 96
:0000192 3402 63050 59732 89 11
:0000064 6265 46611 40721 98 82
:0000128 1895 30429 28654 93 32
oprofile output with kernel 2.6.29-rc2-slqb0121:
CPU: Core 2, speed 2666.76 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
samples % image name app name symbol name
114793 28.7163 vmlinux vmlinux copy_user_generic_string
27880 6.9744 vmlinux vmlinux tg_shares_up
22218 5.5580 vmlinux vmlinux schedule
12238 3.0614 vmlinux vmlinux mwait_idle
7395 1.8499 vmlinux vmlinux task_rq_lock
7348 1.8382 vmlinux vmlinux sock_def_readable
7202 1.8016 vmlinux vmlinux sched_clock_cpu
6981 1.7464 vmlinux vmlinux __skb_recv_datagram
6566 1.6425 vmlinux vmlinux udp_queue_rcv_skb
From: Nick Piggin <hidden> Date: 2009-01-23 08:33:48
On Friday 23 January 2009 14:02:53 Zhang, Yanmin wrote:
1) If I start CPU_NUM clients and servers, SLUB's result is about 2% better
than SLQB's;
I'll have to look into this too. Could be evidence of the possible
TLB improvement from using bigger pages and/or page-specific freelist,
I suppose.
Do you have a scripted used to start netperf in that configuration?
From: Pekka Enberg <hidden> Date: 2009-01-23 08:40:31
On Fri, 2009-01-23 at 16:30 +0800, Zhang, Yanmin wrote:
quoted
I assume binding the client and the server to different physical CPUs
also means that the SKB is always allocated on CPU 1 and freed on CPU
2? If so, we will be taking the __slab_free() slow path all the time on
kfree() which will cause cache effects, no doubt.
But there's another potential performance hit we're taking because the
object size of the cache is so big. As allocations from CPU 1 keep
coming in, we need to allocate new pages and unfreeze the per-cpu page.
That in turn causes __slab_free() to be more eager to discard the slab
(see the PageSlubFrozen check there).
So before going for cache profiling, I'd really like to see an oprofile
report. I suspect we're still going to see much more page allocator
activity
Theoretically, it should, but oprofile doesn't show that.
quoted
there than with SLAB or SLQB which is why we're still behaving
so badly here.
oprofile output with 2.6.29-rc2-slubrevertlarge:
CPU: Core 2, speed 2666.71 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
samples % app name symbol name
132779 32.9951 vmlinux copy_user_generic_string
25334 6.2954 vmlinux schedule
21032 5.2264 vmlinux tg_shares_up
17175 4.2679 vmlinux __skb_recv_datagram
9091 2.2591 vmlinux sock_def_readable
8934 2.2201 vmlinux mwait_idle
8796 2.1858 vmlinux try_to_wake_up
6940 1.7246 vmlinux __slab_free
#slaninfo -AD
Name Objects Alloc Free %Fast
:0000256 1643 5215544 5214027 94 0
kmalloc-8192 28 5189576 5189560 0 0
On Fri, 2009-01-23 at 19:33 +1100, Nick Piggin wrote:
On Friday 23 January 2009 14:02:53 Zhang, Yanmin wrote:
quoted
1) If I start CPU_NUM clients and servers, SLUB's result is about 2% better
than SLQB's;
I'll have to look into this too. Could be evidence of the possible
TLB improvement from using bigger pages and/or page-specific freelist,
I suppose.
Do you have a scripted used to start netperf in that configuration?
See the attachment.
Steps to run testing:
1) compile netperf;
2) Change PROG_DIR to path/to/netperf/src;
3) ./start_netperf_udp_v4.sh 8 #Assume your machine has 8 logical cpus.
From: Pekka Enberg <hidden> Date: 2009-01-23 09:46:50
On Fri, 2009-01-23 at 16:30 +0800, Zhang, Yanmin wrote:
On Fri, 2009-01-23 at 10:06 +0200, Pekka Enberg wrote:
quoted
On Fri, 2009-01-23 at 08:52 +0200, Pekka Enberg wrote:
quoted
quoted
1) If I start CPU_NUM clients and servers, SLUB's result is about 2% better than SLQB's;
2) If I start 1 clinet and 1 server, and bind them to different physical cpu, SLQB's result
is about 10% better than SLUB's.
I don't know why there is still 10% difference with item 2). Maybe cachemiss causes it?
Maybe we can use the perfstat and/or kerneltop utilities of the new perf
counters patch to diagnose this:
http://lkml.org/lkml/2009/1/21/273
And do oprofile, of course. Thanks!
I assume binding the client and the server to different physical CPUs
also means that the SKB is always allocated on CPU 1 and freed on CPU
2? If so, we will be taking the __slab_free() slow path all the time on
kfree() which will cause cache effects, no doubt.
But there's another potential performance hit we're taking because the
object size of the cache is so big. As allocations from CPU 1 keep
coming in, we need to allocate new pages and unfreeze the per-cpu page.
That in turn causes __slab_free() to be more eager to discard the slab
(see the PageSlubFrozen check there).
So before going for cache profiling, I'd really like to see an oprofile
report. I suspect we're still going to see much more page allocator
activity
Theoretically, it should, but oprofile doesn't show that.
That's bit surprising, actually. FWIW, I've included a patch for empty
slab lists. But it's probably not going to help here.
quoted
there than with SLAB or SLQB which is why we're still behaving
so badly here.
Looking at __slab_free(), unless page->inuse is constantly zero and we
discard the slab, it really is just cache effects (10% sounds like a
lot, though!). AFAICT, the only way to optimize that is with Christoph's
unfinished pointer freelists patches or with a remote free list like in
SLQB.
Pekka
From: Pekka Enberg <hidden> Date: 2009-01-23 15:31:49
On Fri, 2009-01-23 at 10:22 -0500, Christoph Lameter wrote:
On Fri, 23 Jan 2009, Pekka Enberg wrote:
quoted
Looking at __slab_free(), unless page->inuse is constantly zero and we
discard the slab, it really is just cache effects (10% sounds like a
lot, though!). AFAICT, the only way to optimize that is with Christoph's
unfinished pointer freelists patches or with a remote free list like in
SLQB.
No there is another way. Increase the allocator order to 3 for the
kmalloc-8192 slab then multiple 8k blocks can be allocated from one of the
larger chunks of data gotten from the page allocator. That will allow slub
to do fast allocs.
I wonder why that doesn't happen already, actually. The slub_max_order
know is capped to PAGE_ALLOC_COSTLY_ORDER ("3") by default and obviously
order 3 should be as good fit as order 2 so 'fraction' can't be too high
either. Hmm.
Pekka
From: Christoph Lameter <hidden> Date: 2009-01-23 15:58:00
On Fri, 23 Jan 2009, Pekka Enberg wrote:
Looking at __slab_free(), unless page->inuse is constantly zero and we
discard the slab, it really is just cache effects (10% sounds like a
lot, though!). AFAICT, the only way to optimize that is with Christoph's
unfinished pointer freelists patches or with a remote free list like in
SLQB.
No there is another way. Increase the allocator order to 3 for the
kmalloc-8192 slab then multiple 8k blocks can be allocated from one of the
larger chunks of data gotten from the page allocator. That will allow slub
to do fast allocs.
From: Pekka Enberg <hidden> Date: 2009-01-23 16:01:56
On Fri, 23 Jan 2009, Pekka Enberg wrote:
quoted
I wonder why that doesn't happen already, actually. The slub_max_order
know is capped to PAGE_ALLOC_COSTLY_ORDER ("3") by default and obviously
order 3 should be as good fit as order 2 so 'fraction' can't be too high
either. Hmm.
On Fri, 2009-01-23 at 10:55 -0500, Christoph Lameter wrote:
The kmalloc-8192 is new. Look at slabinfo output to see what allocation
orders are chosen.
Yes, yes, I know the new cache a result of my patch. I'm just saying
that AFAICT, the existing logic should set the order to 3 but IIRC
Yanmin said it's 2.
Pekka
From: Christoph Lameter <hidden> Date: 2009-01-23 16:57:37
On Fri, 23 Jan 2009, Pekka Enberg wrote:
I wonder why that doesn't happen already, actually. The slub_max_order
know is capped to PAGE_ALLOC_COSTLY_ORDER ("3") by default and obviously
order 3 should be as good fit as order 2 so 'fraction' can't be too high
either. Hmm.
The kmalloc-8192 is new. Look at slabinfo output to see what allocation
orders are chosen.
Any particular reason for killing-off the netserver daemon?
if [ ! -d result ]; then
mkdir result
fi
all_result_files=""
for i in `seq 1 ${client_num}`; do
if [ "${pin_cpu}" == "pin" ]; then
pin_param="-T ${i} ${i}"
The -T option takes arguments of the form:
N - bind both netperf and netserver to core N
N, - bind only netperf to core N, float netserver
,M - float netperf, bind only netserver to core M
N,M - bind netperf to core N and netserver to core M
Without a comma between N and M knuth only knows what the command line parser
will do :)
Same thing here for the -P option - there needs to be a comma between the two
port numbers otherwise, the best case is that the second port number is ignored.
Worst case is that netperf starts doing knuth only knows what.
To get quick profiles, that form of aggregate netperf is OK - just the one
iteration with background processes using a moderatly long run time. However,
for result reporting, it is best to (ab)use the confidence intervals
functionality to try to avoid skew errors. I tend to add-in a global -i 30
option to get each netperf to repeat its measurments 30 times. That way one is
reasonably confident that skew issues are minimized.
http://www.netperf.org/svn/netperf2/trunk/doc/netperf.html#Using-Netperf-to-Measure-Aggregate-Performance
And I would probably add the -c and -C options to have netperf report service
demands.
sub_pid="${sub_pid} `echo $!`"
port_num=$((${port_num}+1))
all_result_files="${all_result_files} ${result_file}"
start_port_server=$((${start_port_server}+1))
start_port_client=$((${start_port_client}+1))
done;
wait ${sub_pid}
killall netserver
result="0"
for i in `echo ${all_result_files}`; do
sub_result=`awk '/Throughput/ {getline; getline; getline; print " "$6}' ${i}`
result=`echo "${result}+${sub_result}"|bc`
done;
The documented-only-in-source :( "omni" tests in top-of-trunk netperf:
http://www.netperf.org/svn/netperf2/trunk
./configure --enable-omni
allow one to specify which result values one wants, in which order, either as
more or less traditional netperf output (test-specific -O), CSV (test-specific
-o) or keyval (test-specific -k). All three take an optional filename as an
argument with the file containing a list of desired output values. You can give
a "filename" of '?' to get the list of output values known to that version of
netperf.
Might help simplify parsing and whatnot.
happy benchmarking,
rick jones
From: Grant Grundler <hidden> Date: 2009-01-23 18:51:41
On Fri, Jan 23, 2009 at 10:40 AM, Rick Jones [off-list ref] wrote:
...
And I would probably add the -c and -C options to have netperf report
service demands.
For performance analysis, the service demand is often more interesting
than the absolute performance (which typically only varies a few Mb/s
for gigE NICs). I strongly encourage adding -c and -C.
grant
On Fri, 2009-01-23 at 10:22 -0500, Christoph Lameter wrote:
On Fri, 23 Jan 2009, Pekka Enberg wrote:
quoted
Looking at __slab_free(), unless page->inuse is constantly zero and we
discard the slab, it really is just cache effects (10% sounds like a
lot, though!). AFAICT, the only way to optimize that is with Christoph's
unfinished pointer freelists patches or with a remote free list like in
SLQB.
No there is another way. Increase the allocator order to 3 for the
kmalloc-8192 slab then multiple 8k blocks can be allocated from one of the
larger chunks of data gotten from the page allocator. That will allow slub
to do fast allocs.
After I change kmalloc-8192/order to 3, the result(pinned netperf UDP-U-4k)
difference between SLUB and SLQB becomes 1% which can be considered as fluctuation.
But when trying to increased it to 4, I got:
[root@lkp-st02-x8664 slab]# echo "3">kmalloc-8192/order
[root@lkp-st02-x8664 slab]# echo "4">kmalloc-8192/order
-bash: echo: write error: Invalid argument
Comparing with SLQB, it seems SLUB needs too many investigation/manual finer-tuning
against specific benchmarks. One hard is to tune page order number. Although SLQB also
has many tuning options, I almost doesn't tune it manually, just run benchmark and
collect results to compare. Does that mean the scalability of SLQB is better?
Any particular reason for killing-off the netserver daemon?
I'm not sure if prior running might leave any impact on later running, so
just kill netserver.
quoted
if [ ! -d result ]; then
mkdir result
fi
all_result_files=""
for i in `seq 1 ${client_num}`; do
if [ "${pin_cpu}" == "pin" ]; then
pin_param="-T ${i} ${i}"
The -T option takes arguments of the form:
N - bind both netperf and netserver to core N
N, - bind only netperf to core N, float netserver
,M - float netperf, bind only netserver to core M
N,M - bind netperf to core N and netserver to core M
Without a comma between N and M knuth only knows what the command line parser
will do :)
Same thing here for the -P option - there needs to be a comma between the two
port numbers otherwise, the best case is that the second port number is ignored.
Worst case is that netperf starts doing knuth only knows what.
Thanks.
To get quick profiles, that form of aggregate netperf is OK - just the one
iteration with background processes using a moderatly long run time. However,
for result reporting, it is best to (ab)use the confidence intervals
functionality to try to avoid skew errors.
Yes. My formal testing uses -i 50. I just wanted a quick testing. If I need
finer-tuning or investigation, I would turn on more options.
Yes. That's good. I'm used to start vmstat or mpstat to monitor cpu utilization
in real time.
quoted
sub_pid="${sub_pid} `echo $!`"
port_num=$((${port_num}+1))
all_result_files="${all_result_files} ${result_file}"
start_port_server=$((${start_port_server}+1))
start_port_client=$((${start_port_client}+1))
done;
wait ${sub_pid}
killall netserver
result="0"
for i in `echo ${all_result_files}`; do
sub_result=`awk '/Throughput/ {getline; getline; getline; print " "$6}' ${i}`
result=`echo "${result}+${sub_result}"|bc`
done;
The documented-only-in-source :( "omni" tests in top-of-trunk netperf:
http://www.netperf.org/svn/netperf2/trunk
./configure --enable-omni
allow one to specify which result values one wants, in which order, either as
more or less traditional netperf output (test-specific -O), CSV (test-specific
-o) or keyval (test-specific -k). All three take an optional filename as an
argument with the file containing a list of desired output values. You can give
a "filename" of '?' to get the list of output values known to that version of
netperf.
Might help simplify parsing and whatnot.
From: Pekka Enberg <hidden> Date: 2009-01-24 07:37:46
On Fri, 2009-01-23 at 10:22 -0500, Christoph Lameter wrote:
quoted
No there is another way. Increase the allocator order to 3 for the
kmalloc-8192 slab then multiple 8k blocks can be allocated from one of the
larger chunks of data gotten from the page allocator. That will allow slub
to do fast allocs.
On Sat, Jan 24, 2009 at 4:55 AM, Zhang, Yanmin
[off-list ref] wrote:
After I change kmalloc-8192/order to 3, the result(pinned netperf UDP-U-4k)
difference between SLUB and SLQB becomes 1% which can be considered as fluctuation.
Great. We should fix calculate_order() to be order 3 for kmalloc-8192.
Are you interested in doing that?
On Sat, Jan 24, 2009 at 4:55 AM, Zhang, Yanmin
[off-list ref] wrote:
But when trying to increased it to 4, I got:
[root@lkp-st02-x8664 slab]# echo "3">kmalloc-8192/order
[root@lkp-st02-x8664 slab]# echo "4">kmalloc-8192/order
-bash: echo: write error: Invalid argument
That's probably because max order is capped to 3. You can change that
by passing slub_max_order=<n> as kernel parameter.
On Sat, Jan 24, 2009 at 4:55 AM, Zhang, Yanmin
[off-list ref] wrote:
Comparing with SLQB, it seems SLUB needs too many investigation/manual finer-tuning
against specific benchmarks. One hard is to tune page order number. Although SLQB also
has many tuning options, I almost doesn't tune it manually, just run benchmark and
collect results to compare. Does that mean the scalability of SLQB is better?
One thing is sure, SLUB seems to be hard to tune. Probably because
it's dependent on the page order so much.
From: Christoph Lameter <hidden> Date: 2009-01-26 17:57:58
On Sat, 24 Jan 2009, Zhang, Yanmin wrote:
But when trying to increased it to 4, I got:
[root@lkp-st02-x8664 slab]# echo "3">kmalloc-8192/order
[root@lkp-st02-x8664 slab]# echo "4">kmalloc-8192/order
-bash: echo: write error: Invalid argument
This is because 4 is more than the maximum allowed order. You can
reconfigure that by setting
slub_max_order=5
or so on boot.
From: Rick Jones <hidden> Date: 2009-01-26 18:26:39
quoted
To get quick profiles, that form of aggregate netperf is OK - just the one
iteration with background processes using a moderatly long run time. However,
for result reporting, it is best to (ab)use the confidence intervals
functionality to try to avoid skew errors.
Yes. My formal testing uses -i 50. I just wanted a quick testing. If I need
finer-tuning or investigation, I would turn on more options.
Netperf will silently clip that to 30 as that is all the built-in tables know.
Thanks again. I learned a lot.
Feel free to wander over to netperf-talk over at netperf.org if you want to talk
some more about the care and feeding of netperf.
happy benchmarking,
rick jones
On Mon, 2009-01-26 at 12:36 -0500, Christoph Lameter wrote:
On Sat, 24 Jan 2009, Zhang, Yanmin wrote:
quoted
But when trying to increased it to 4, I got:
[root@lkp-st02-x8664 slab]# echo "3">kmalloc-8192/order
[root@lkp-st02-x8664 slab]# echo "4">kmalloc-8192/order
-bash: echo: write error: Invalid argument
This is because 4 is more than the maximum allowed order. You can
reconfigure that by setting
slub_max_order=5
or so on boot.
With slub_max_order=5, the default order of kmalloc-8192 becomes
5. I tested it with netperf UDP-U-4k and the result difference from
SLAB/SLQB is less than 1% which is really fluctuation.
On Sat, 2009-01-24 at 09:36 +0200, Pekka Enberg wrote:
On Fri, 2009-01-23 at 10:22 -0500, Christoph Lameter wrote:
quoted
quoted
No there is another way. Increase the allocator order to 3 for the
kmalloc-8192 slab then multiple 8k blocks can be allocated from one of the
larger chunks of data gotten from the page allocator. That will allow slub
to do fast allocs.
On Sat, Jan 24, 2009 at 4:55 AM, Zhang, Yanmin
[off-list ref] wrote:
quoted
After I change kmalloc-8192/order to 3, the result(pinned netperf UDP-U-4k)
difference between SLUB and SLQB becomes 1% which can be considered as fluctuation.
Great. We should fix calculate_order() to be order 3 for kmalloc-8192.
Are you interested in doing that?
Pekka,
Sorry for the late update.
The default order of kmalloc-8192 on 2*4 stoakley is really an issue of calculate_order.
slab_size order name
-------------------------------------------------
4096 3 sgpool-128
8192 2 kmalloc-8192
16384 3 kmalloc-16384
kmalloc-8192's default order is smaller than sgpool-128's.
On 4*4 tigerton machine, a similiar issue appears on another kmem_cache.
Function calculate_order uses 'min_objects /= 2;' to shrink. Plus size calculation/checking
in slab_order, sometimes above issue appear.
Below patch against 2.6.29-rc2 fixes it.
I checked the default orders of all kmem_cache and they don't become smaller than before. So
the patch wouldn't hurt performance.
Signed-off-by Zhang Yanmin [off-list ref]
---
diff -Nraup linux-2.6.29-rc2/mm/slub.c linux-2.6.29-rc2_slubcalc_order/mm/slub.c
On Thu, 2009-02-12 at 13:22 +0800, Zhang, Yanmin wrote:
On Sat, 2009-01-24 at 09:36 +0200, Pekka Enberg wrote:
quoted
On Fri, 2009-01-23 at 10:22 -0500, Christoph Lameter wrote:
quoted
quoted
No there is another way. Increase the allocator order to 3 for the
kmalloc-8192 slab then multiple 8k blocks can be allocated from one of the
larger chunks of data gotten from the page allocator. That will allow slub
to do fast allocs.
On Sat, Jan 24, 2009 at 4:55 AM, Zhang, Yanmin
[off-list ref] wrote:
quoted
After I change kmalloc-8192/order to 3, the result(pinned netperf UDP-U-4k)
difference between SLUB and SLQB becomes 1% which can be considered as fluctuation.
Great. We should fix calculate_order() to be order 3 for kmalloc-8192.
Are you interested in doing that?
Pekka,
Sorry for the late update.
The default order of kmalloc-8192 on 2*4 stoakley is really an issue of calculate_order.
Oh, previous patch has a compiling warning. Pls. use below patch.
From: Zhang Yanmin <redacted>
The default order of kmalloc-8192 on 2*4 stoakley is an issue of calculate_order.
slab_size order name
-------------------------------------------------
4096 3 sgpool-128
8192 2 kmalloc-8192
16384 3 kmalloc-16384
kmalloc-8192's default order is smaller than sgpool-128's.
On 4*4 tigerton machine, a similiar issue appears on another kmem_cache.
Function calculate_order uses 'min_objects /= 2;' to shrink. Plus size calculation/checking
in slab_order, sometimes above issue appear.
Below patch against 2.6.29-rc2 fixes it.
I checked the default orders of all kmem_cache and they don't become smaller than before. So
the patch wouldn't hurt performance.
Signed-off-by Zhang Yanmin [off-list ref]
---
@@ -1844,6 +1844,7 @@ static inline int calculate_order(int siintorder;intmin_objects;intfraction;+intmax_objects;/**Attempttofindbestconfigurationforaslab.This
@@ -1856,6 +1857,9 @@ static inline int calculate_order(int simin_objects=slub_min_objects;if(!min_objects)min_objects=4*(fls(nr_cpu_ids)+1);+max_objects=(PAGE_SIZE<<slub_max_order)/size;+min_objects=min(min_objects,max_objects);+while(min_objects>1){fraction=16;while(fraction>=4){
@@ -1865,7 +1869,7 @@ static inline int calculate_order(int sireturnorder;fraction/=2;}-min_objects/=2;+min_objects--;}/*--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Christoph Lameter <hidden> Date: 2009-02-12 15:48:59
On Thu, 12 Feb 2009, Zhang, Yanmin wrote:
The default order of kmalloc-8192 on 2*4 stoakley is an issue of calculate_order.
slab_size order name
-------------------------------------------------
4096 3 sgpool-128
8192 2 kmalloc-8192
16384 3 kmalloc-16384
kmalloc-8192's default order is smaller than sgpool-128's.
You reverted the page allocator passthrough patch before this right?
Otherwise kmalloc-8192 should not exist and allocation calls for 8192
bytes would be converted inline to request of an order 1 page from the
page allocator.
From: Pekka Enberg <hidden> Date: 2009-02-12 16:03:50
On Sat, 2009-01-24 at 09:36 +0200, Pekka Enberg wrote:
quoted
quoted
On Fri, 2009-01-23 at 10:22 -0500, Christoph Lameter wrote:
quoted
quoted
No there is another way. Increase the allocator order to 3 for the
kmalloc-8192 slab then multiple 8k blocks can be allocated from one of the
larger chunks of data gotten from the page allocator. That will allow slub
to do fast allocs.
On Sat, Jan 24, 2009 at 4:55 AM, Zhang, Yanmin
[off-list ref] wrote:
quoted
After I change kmalloc-8192/order to 3, the result(pinned netperf UDP-U-4k)
difference between SLUB and SLQB becomes 1% which can be considered as fluctuation.
Great. We should fix calculate_order() to be order 3 for kmalloc-8192.
Are you interested in doing that?
On Thu, 2009-02-12 at 13:22 +0800, Zhang, Yanmin wrote:
quoted
Pekka,
Sorry for the late update.
The default order of kmalloc-8192 on 2*4 stoakley is really an issue of calculate_order.
On Thu, 2009-02-12 at 13:47 +0800, Zhang, Yanmin wrote:
Oh, previous patch has a compiling warning. Pls. use below patch.
From: Zhang Yanmin <redacted>
The default order of kmalloc-8192 on 2*4 stoakley is an issue of calculate_order.
Applied to the 'topic/slub/perf' branch. Thanks!
Pekka
From: Pekka Enberg <hidden> Date: 2009-02-12 16:08:17
Hi Christoph,
On Thu, 12 Feb 2009, Zhang, Yanmin wrote:
quoted
The default order of kmalloc-8192 on 2*4 stoakley is an issue of calculate_order.
slab_size order name
-------------------------------------------------
4096 3 sgpool-128
8192 2 kmalloc-8192
16384 3 kmalloc-16384
kmalloc-8192's default order is smaller than sgpool-128's.
On Thu, Feb 12, 2009 at 5:25 PM, Christoph Lameter
[off-list ref] wrote:
You reverted the page allocator passthrough patch before this right?
Otherwise kmalloc-8192 should not exist and allocation calls for 8192
bytes would be converted inline to request of an order 1 page from the
page allocator.