All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: RFC: New API for PPC for vcpu mmu access
From: Scott Wood @ 2011-02-07 18:52 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Yoder Stuart-B08248, Wood Scott-B07421, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org, qemu-devel@nongnu.org
In-Reply-To: <E32F37BC-71EF-44A9-825D-50F61B675463@suse.de>

On Mon, 7 Feb 2011 17:49:51 +0100
Alexander Graf <agraf@suse.de> wrote:

> 
> On 07.02.2011, at 17:40, Yoder Stuart-B08248 wrote:
> 
> > Suggested change to this would be to have Qemu set tlb_type as 
> > an _input_ argument.   If KVM supports it, that type gets used,
> > else an error is returned.    This would allow Qemu to tell
> > the kernel what type of MMU it is prepared to support.   Without
> > this Qemu would just have to error out if the type returned is
> > unknown.
> 
> Yes, we could use the same struct for get and set. On set, it could transfer the mmu type, on get it could tell userspace the mmu type.

What happens if a get is done before the first set, and there are
multiple MMU type options for this hardware, with differing entry sizes?

Qemu would have to know beforehand how large to make the buffer.

We could say that going forward, it's expected that qemu will do a
TLB set (either a full one, or a lightweight alternative) after
creating a vcpu.  For compatibility, if this doesn't happen before the
vcpu is run, the TLB is created and initialized as it is today, but
no new Qemu-visible features will be enabled that way.

If Qemu does a get without ever doing some set operation, it should
get an error, since the requirement to do a set is added at the same
time as the get API.

-Scott


^ permalink raw reply

* Re: RFC: New API for PPC for vcpu mmu access
From: Scott Wood @ 2011-02-07 18:52 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Yoder Stuart-B08248, Wood Scott-B07421, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org, qemu-devel@nongnu.org
In-Reply-To: <E32F37BC-71EF-44A9-825D-50F61B675463@suse.de>

On Mon, 7 Feb 2011 17:49:51 +0100
Alexander Graf <agraf@suse.de> wrote:

> 
> On 07.02.2011, at 17:40, Yoder Stuart-B08248 wrote:
> 
> > Suggested change to this would be to have Qemu set tlb_type as 
> > an _input_ argument.   If KVM supports it, that type gets used,
> > else an error is returned.    This would allow Qemu to tell
> > the kernel what type of MMU it is prepared to support.   Without
> > this Qemu would just have to error out if the type returned is
> > unknown.
> 
> Yes, we could use the same struct for get and set. On set, it could transfer the mmu type, on get it could tell userspace the mmu type.

What happens if a get is done before the first set, and there are
multiple MMU type options for this hardware, with differing entry sizes?

Qemu would have to know beforehand how large to make the buffer.

We could say that going forward, it's expected that qemu will do a
TLB set (either a full one, or a lightweight alternative) after
creating a vcpu.  For compatibility, if this doesn't happen before the
vcpu is run, the TLB is created and initialized as it is today, but
no new Qemu-visible features will be enabled that way.

If Qemu does a get without ever doing some set operation, it should
get an error, since the requirement to do a set is added at the same
time as the get API.

-Scott


^ permalink raw reply

* Re: [PATCH 17/46] fs: Use rename lock and RCU for multi-step operations
From: Jim Schutt @ 2011-02-07 18:52 UTC (permalink / raw)
  To: Nick Piggin
  Cc: Yehuda Sadeh Weinraub, Nick Piggin, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org, Sage Weil,
	ceph-devel@vger.kernel.org
In-Reply-To: <AANLkTinmaojfNDYk1i4jMP33MmEQDur9XZvFp=qhV01e@mail.gmail.com>


On Wed, 2011-01-26 at 22:18 -0700, Nick Piggin wrote:
> On Wed, Jan 26, 2011 at 9:10 AM, Yehuda Sadeh Weinraub
> <yehudasa@gmail.com> wrote:
> > On Wed, Jan 19, 2011 at 2:32 PM, Nick Piggin <npiggin@gmail.com> wrote:
> >> On Thu, Jan 20, 2011 at 9:27 AM, Yehuda Sadeh Weinraub
> >> <yehudasa@gmail.com> wrote:
> >>> On Tue, Jan 18, 2011 at 2:42 PM, Nick Piggin <npiggin@gmail.com> wrote:
> >>>> On Wed, Jan 19, 2011 at 9:32 AM, Yehuda Sadeh Weinraub
> >>>
> >>>>> There's an issue with ceph as it references the
> >>>>> dentry->d_parent(->d_inode) at dentry_release(), so setting
> >>>>> dentry->d_parent to NULL here doesn't work with ceph. Though there is
> >>>>> some workaround for it, we would like to be sure that this one is
> >>>>> really required so that we don't exacerbate the ugliness. The
> >>>>> workaround is to keep a pointer to the parent inode in the private
> >>>>> dentry structure, which will be referenced only at the .release()
> >>>>> callback. This is clearly not ideal.
> >>>>
> >>>> Hmm, I'll have to think about it. Probably we can check for
> >>>> d_count == 0 rather than parent != NULL I think?
> >>>>
> >>>
> >>> That'll solve ceph's problem, don't know about how'd affect other
> >>> stuff. We'll need to know whether this is the solution, or whether
> >>> we'd need to introduce some other band aid fix.
> >>
> >> No I think it will work fine. Basically we just need to know whether
> >> we have been deleted, and if so then we restart rather than walking
> >> back up the parent.
> >>
> >> I'll send a patch in a few days. For the meantime, it's a rathe
> >> small window for ceph to worry about. So we'll have something
> >> before -rc2 which should be OK.
> >>
> >
> > I guess that it's a bit late for -rc2, should we assume that it'll be on -rc3?
> 
> Yeah, I'm sorry I've been travelling and a bit disconnected.
> 
> NFS folk are having a similar problem and looks like similar
> proposed fix will do it.
> 
> http://marc.info/?l=linux-fsdevel&m=129599823927039&w=2
> 
> So I think it is the best way to go to restore behaviour back to what
> filesystems already expect, to avoid more surprises in future.

I think the following BUG indicates I'm hitting this problem?
All I have to do to cause it is unlink a file.

My ceph client kernel is 8dbdea8444 (master branch) from 
  git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+ e41cdbb6c5 (master branch) + a3f5274e53 (unstable branch)
  from git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git

Are there any patches available for this I can test?

Thanks -- Jim

[ 1471.018973] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
[ 1471.019909] IP: [<ffffffffa0748275>] ceph_dentry_release+0x31/0x148 [ceph]
[ 1471.019909] PGD 121fb9067 PUD 120520067 PMD 0 
[ 1471.019909] Oops: 0000 [#1] SMP 
[ 1471.019909] last sysfs file: /sys/block/md0/range
[ 1471.019909] CPU 1 
[ 1471.019909] Modules linked in: ceph libceph ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack ipt_REJECT xt_tcpudp iptable_filter ip_tables x_tables bridge stp i2c_dev i2c_core ext3 jbd be2iscsi iscsi_boot_sysfs iscsi]
[ 1471.019909] 
[ 1471.019909] Pid: 20, comm: kworker/1:1 Not tainted 2.6.38-rc3-00247-g4a9cd22 #13 0UR033/PowerEdge 1950
[ 1471.019909] RIP: 0010:[<ffffffffa0748275>]  [<ffffffffa0748275>] ceph_dentry_release+0x31/0x148 [ceph]
[ 1471.019909] RSP: 0018:ffff88012b09ba20  EFLAGS: 00010286
[ 1471.019909] RAX: 0000000000000000 RBX: ffff880129e3f0c0 RCX: ffff88011d448280
[ 1471.019909] RDX: 000000000000cbc0 RSI: 0000000000000001 RDI: ffff880129e3f0c0
[ 1471.019909] RBP: ffff88012b09ba60 R08: 0000000000000000 R09: ffff88012b09b9e0
[ 1471.019909] R10: 000001000000fa40 R11: ffff88012b09ba20 R12: ffff88011d448840
[ 1471.019909] R13: 0000000000000000 R14: ffff880129e3f0c0 R15: ffff88011d416000
[ 1471.019909] FS:  0000000000000000(0000) GS:ffff8800cfc40000(0000) knlGS:0000000000000000
[ 1471.019909] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 1471.019909] CR2: 0000000000000030 CR3: 0000000128a1b000 CR4: 00000000000006e0
[ 1471.019909] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 1471.019909] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 1471.019909] Process kworker/1:1 (pid: 20, threadinfo ffff88012b09a000, task ffff88012b0a8000)
[ 1471.019909] Stack:
[ 1471.019909]  ffff88011d448840 ffff880128f89800 fffffffffffffffe ffff880129e3f0c0
[ 1471.019909]  ffff88011d448840 ffff880129fa70c0 0000000000000001 ffff880120f86000
[ 1471.019909]  ffff88012b09ba80 ffffffff81104007 ffff880129e3f0c0 ffff880129fa70c0
[ 1471.019909] Call Trace:
[ 1471.019909]  [<ffffffff81104007>] d_free+0x37/0x5c
[ 1471.019909]  [<ffffffff811048d4>] dentry_kill+0x11a/0x126
[ 1471.019909]  [<ffffffff8110523d>] dput+0xbc/0xc9
[ 1471.019909]  [<ffffffffa076099c>] ceph_mdsc_release_request+0xa9/0x117 [ceph]
[ 1471.019909]  [<ffffffffa07608f3>] ? ceph_mdsc_release_request+0x0/0x117 [ceph]
[ 1471.019909]  [<ffffffff811ab542>] kref_put+0x43/0x4f
[ 1471.019909]  [<ffffffffa075bab9>] ceph_mdsc_put_request+0x1c/0x1e [ceph]
[ 1471.019909]  [<ffffffffa075fc26>] dispatch+0xbdc/0x1282 [ceph]
[ 1471.019909]  [<ffffffff81192c70>] ? chksum_update+0x15/0x1d
[ 1471.019909]  [<ffffffff8118cf30>] ? crypto_shash_update+0x1f/0x21
[ 1471.019909]  [<ffffffff812cf943>] ? kernel_recvmsg+0x3a/0x46
[ 1471.019909]  [<ffffffffa0704c69>] ? ceph_tcp_recvmsg+0x4e/0x5b [libceph]
[ 1471.019909]  [<ffffffffa07066ce>] try_read+0x1363/0x1508 [libceph]
[ 1471.019909]  [<ffffffff81030af3>] ? should_resched+0xe/0x2f
[ 1471.019909]  [<ffffffffa0707318>] con_work+0xec/0x1426 [libceph]
[ 1471.019909]  [<ffffffff81030adb>] ? need_resched+0x23/0x2d
[ 1471.019909]  [<ffffffff8136f43a>] ? schedule+0x68d/0x6a7
[ 1471.019909]  [<ffffffff8104e9d5>] ? add_timer+0x1c/0x1e
[ 1471.019909]  [<ffffffff81058341>] ? queue_delayed_work_on+0xde/0xf2
[ 1471.019909]  [<ffffffff81056dc5>] process_one_work+0x16e/0x26a
[ 1471.019909]  [<ffffffffa070722c>] ? con_work+0x0/0x1426 [libceph]
[ 1471.019909]  [<ffffffff8105852d>] ? worker_thread+0x0/0x183
[ 1471.019909]  [<ffffffff810585f0>] worker_thread+0xc3/0x183
[ 1471.019909]  [<ffffffff8105be62>] kthread+0x72/0x7a
[ 1471.019909]  [<ffffffff81003914>] kernel_thread_helper+0x4/0x10
[ 1471.019909]  [<ffffffff8105bdf0>] ? kthread+0x0/0x7a
[ 1471.019909]  [<ffffffff81003910>] ? kernel_thread_helper+0x0/0x10
[ 1471.019909] Code: 41 56 41 55 41 54 53 48 83 ec 18 0f 1f 44 00 00 48 8b 47 18 45 31 ed 4c 8b 7f 78 49 89 fe 48 c7 45 d0 fe ff ff ff 48 39 c7 74 14 <4c> 8b 68 30 4d 85 ed 74 0b 49 8b 85 08 fd ff ff 48 89 45 d0 80 
[ 1471.019909] RIP  [<ffffffffa0748275>] ceph_dentry_release+0x31/0x148 [ceph]
[ 1471.019909]  RSP <ffff88012b09ba20>
[ 1471.019909] CR2: 0000000000000030
[ 1471.455942] ---[ end trace 782e52b3ca82de3c ]---
[ 1471.460581] BUG: unable to handle kernel paging request at fffffffffffffff8
[ 1471.461551] IP: [<ffffffff8105bb0e>] kthread_data+0x10/0x16
[ 1471.461551] PGD 1805067 PUD 1806067 PMD 0 
[ 1471.461551] Oops: 0000 [#2] SMP 
[ 1471.461551] last sysfs file: /sys/block/md0/range
[ 1471.461551] CPU 1 
[ 1471.461551] Modules linked in: ceph libceph ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack ipt_REJECT xt_tcpudp iptable_filter ip_tables x_tables bridge stp i2c_dev i2c_core ext3 jbd be2iscsi iscsi_boot_sysfs iscsi]
[ 1471.461551] 
[ 1471.461551] Pid: 20, comm: kworker/1:1 Tainted: G      D     2.6.38-rc3-00247-g4a9cd22 #13 0UR033/PowerEdge 1950
[ 1471.461551] RIP: 0010:[<ffffffff8105bb0e>]  [<ffffffff8105bb0e>] kthread_data+0x10/0x16
[ 1471.461551] RSP: 0018:ffff88012b09b5b8  EFLAGS: 00010092
[ 1471.461551] RAX: 0000000000000000 RBX: 0000000000000001 RCX: ffff88012b0a8000
[ 1471.461551] RDX: 000000000000cbc0 RSI: 0000000000000001 RDI: ffff88012b0a8000
[ 1471.461551] RBP: ffff88012b09b5b8 R08: ffff8800cfc54f40 R09: dead000000200200
[ 1471.461551] R10: dead000000200200 R11: 0000000000000002 R12: 00007ffffffff000
[ 1471.461551] R13: 0000000000000001 R14: ffff8800cfc51cc0 R15: 0000000000000001
[ 1471.461551] FS:  0000000000000000(0000) GS:ffff8800cfc40000(0000) knlGS:0000000000000000
[ 1471.461551] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 1471.461551] CR2: fffffffffffffff8 CR3: 0000000128a1b000 CR4: 00000000000006e0
[ 1471.461551] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 1471.461551] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 1471.461551] Process kworker/1:1 (pid: 20, threadinfo ffff88012b09a000, task ffff88012b0a8000)
[ 1471.461551] Stack:
[ 1471.461551]  ffff88012b09b5e8 ffffffff810583d7 ffff88012b09b5f8 0000000000000001
[ 1471.461551]  00007ffffffff000 0000000000011cc0 ffff88012b09b6f8 ffffffff8136ef22
[ 1471.461551]  ffff88012b09b618 ffff88012b0a8000 ffff88012b6b0850 ffff88012b0a83a0
[ 1471.461551] Call Trace:
[ 1471.461551]  [<ffffffff810583d7>] wq_worker_sleeping+0x1a/0x87
[ 1471.461551]  [<ffffffff8136ef22>] schedule+0x175/0x6a7
[ 1471.461551]  [<ffffffff8108b8d0>] ? call_rcu_sched+0x15/0x17
[ 1471.461551]  [<ffffffff810e8b0e>] ? __slab_free+0x52/0xe9
[ 1471.461551]  [<ffffffff8108b8d0>] ? call_rcu_sched+0x15/0x17
[ 1471.461551]  [<ffffffff810443f2>] ? release_task+0x32b/0x343
[ 1471.461551]  [<ffffffff810601df>] ? switch_task_namespaces+0x1d/0x51
[ 1471.461551]  [<ffffffff810456cf>] do_exit+0x678/0x692
[ 1471.461551]  [<ffffffff81371b59>] oops_end+0xb7/0xbf
[ 1471.461551]  [<ffffffff81026de1>] no_context+0x1fa/0x209
[ 1471.461551]  [<ffffffff81027076>] __bad_area_nosemaphore+0x187/0x1aa
[ 1471.461551]  [<ffffffff810b517d>] ? __pagevec_free+0x70/0x8c
[ 1471.461551]  [<ffffffff810b8ab2>] ? hpage_nr_pages+0x1a/0x2c
[ 1471.461551]  [<ffffffff81027123>] bad_area_nosemaphore+0x13/0x18
[ 1471.461551]  [<ffffffff81373aa5>] do_page_fault+0x175/0x325
[ 1471.461551]  [<ffffffff810afe20>] ? find_get_pages+0x44/0xbb
[ 1471.461551]  [<ffffffffa075070b>] ? list_add+0x11/0x13 [ceph]
[ 1471.461551]  [<ffffffffa0753773>] ? ceph_put_cap+0xf6/0x12d [ceph]
[ 1471.461551]  [<ffffffff810b9611>] ? pagevec_lookup+0x24/0x2d
[ 1471.461551]  [<ffffffff813710df>] page_fault+0x1f/0x30
[ 1471.461551]  [<ffffffffa0748275>] ? ceph_dentry_release+0x31/0x148 [ceph]
[ 1471.461551]  [<ffffffff81104007>] d_free+0x37/0x5c
[ 1471.461551]  [<ffffffff811048d4>] dentry_kill+0x11a/0x126
[ 1471.461551]  [<ffffffff8110523d>] dput+0xbc/0xc9
[ 1471.461551]  [<ffffffffa076099c>] ceph_mdsc_release_request+0xa9/0x117 [ceph]
[ 1471.461551]  [<ffffffffa07608f3>] ? ceph_mdsc_release_request+0x0/0x117 [ceph]
[ 1471.461551]  [<ffffffff811ab542>] kref_put+0x43/0x4f
[ 1471.461551]  [<ffffffffa075bab9>] ceph_mdsc_put_request+0x1c/0x1e [ceph]
[ 1471.461551]  [<ffffffffa075fc26>] dispatch+0xbdc/0x1282 [ceph]
[ 1471.461551]  [<ffffffff81192c70>] ? chksum_update+0x15/0x1d
[ 1471.461551]  [<ffffffff8118cf30>] ? crypto_shash_update+0x1f/0x21
[ 1471.461551]  [<ffffffff812cf943>] ? kernel_recvmsg+0x3a/0x46
[ 1471.461551]  [<ffffffffa0704c69>] ? ceph_tcp_recvmsg+0x4e/0x5b [libceph]
[ 1471.461551]  [<ffffffffa07066ce>] try_read+0x1363/0x1508 [libceph]
[ 1471.461551]  [<ffffffff81030af3>] ? should_resched+0xe/0x2f
[ 1471.461551]  [<ffffffffa0707318>] con_work+0xec/0x1426 [libceph]
[ 1471.461551]  [<ffffffff81030adb>] ? need_resched+0x23/0x2d
[ 1471.461551]  [<ffffffff8136f43a>] ? schedule+0x68d/0x6a7
[ 1471.461551]  [<ffffffff8104e9d5>] ? add_timer+0x1c/0x1e
[ 1471.461551]  [<ffffffff81058341>] ? queue_delayed_work_on+0xde/0xf2
[ 1471.461551]  [<ffffffff81056dc5>] process_one_work+0x16e/0x26a
[ 1471.461551]  [<ffffffffa070722c>] ? con_work+0x0/0x1426 [libceph]
[ 1471.461551]  [<ffffffff8105852d>] ? worker_thread+0x0/0x183
[ 1471.461551]  [<ffffffff810585f0>] worker_thread+0xc3/0x183
[ 1471.461551]  [<ffffffff8105be62>] kthread+0x72/0x7a
[ 1471.461551]  [<ffffffff81003914>] kernel_thread_helper+0x4/0x10
[ 1471.461551]  [<ffffffff8105bdf0>] ? kthread+0x0/0x7a
[ 1471.461551]  [<ffffffff81003910>] ? kernel_thread_helper+0x0/0x10
[ 1471.461551] Code: e5 0f 1f 44 00 00 65 48 8b 04 25 80 b5 00 00 48 8b 80 48 03 00 00 8b 40 f0 c9 c3 55 48 89 e5 0f 1f 44 00 00 48 8b 87 48 03 00 00 <48> 8b 40 f8 c9 c3 55 48 89 e5 0f 1f 44 00 00 48 8d 47 08 c7 07 
[ 1471.461551] RIP  [<ffffffff8105bb0e>] kthread_data+0x10/0x16
[ 1471.461551]  RSP <ffff88012b09b5b8>
[ 1471.461551] CR2: fffffffffffffff8
[ 1471.461551] ---[ end trace 782e52b3ca82de3d ]---
[ 1471.461551] Fixing recursive fault but reboot is needed!

> 
> Thanks,
> Nick
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



^ permalink raw reply

* Re: [lm-sensors] Standalone driver for W83677HG-I, NCT6775F,
From: Guenter Roeck @ 2011-02-07 18:48 UTC (permalink / raw)
  To: lm-sensors
In-Reply-To: <20110205175852.GA26672@ericsson.com>

On Mon, Feb 07, 2011 at 01:20:22PM -0500, Andrew Lutomirski wrote:
> On Mon, Feb 7, 2011 at 12:58 PM, Guenter Roeck
> <guenter.roeck@ericsson.com> wrote:
> > Hi all,
> >
> > I published a new version of the standalone driver for W83667HG-I (NCT6771F, NCT6775F)
> > and NCT6776F at http://roeck-us.net/linux/drivers/w83627ehf/.
> >
> > Key changes are listed in the README file. Most of the reported bugs have been fixed,
> > though I am not sure about PWM configuration on NCT6775F and fan min limits on NCT6776F.
> >
> 
> I don't see a README.  What's w83627ehf.c.18?
> 
Sorry, it is there now. w83627ehf.c.18 is a port of rev1 to 2.6.18.

> > For PWM configuration on NCT6775F, I did not find a problem
> . I can set and read PWM values,
> > but since my board does not connect the chip to actual fans I have no idea if the settings
> > have any effect. So this will need to be re-tested on a board which actually uses the chip
> > for fan control.
> 
> Something's weird.
> 
> # cat pwm2_enable
> 5

5 means it is running in SmartFan IV mode.

> # cat pwm2_mode
> 1
> # echo 1 >pwm2_enable
> # cat pwm2_enable
> 5
> # echo 1 >pwm2_enable
> # cat pwm2_enable
> 5
> # echo 2 >pwm2_enable
> # cat pwm2_enable
> 6
> 
That was a bug. 

> [fiddle with pwm2 here.  values written stick but have no effect.]
> 
> # echo 3 >pwm2_enable
> [root@midnight w83627ehf.656]# cat pwm2_enable
> 8
> [root@midnight w83627ehf.656]# echo 1 >pwm2_enable
> [root@midnight w83627ehf.656]# cat pwm2_enable
> 8
> 
> Note: I won't swear that my motherboard uses this particular chip to
> drive the PWMs, but I assume it does since it can certainly measure
> fan speed w/ this chip and it controls the PWMs somehow.
> 
It uses it per Intel specifications.

Anyway, please try again. I updated the code to fix the pwmX_enable bug.

Thanks,
Guenter

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply

* Re: Laptop Function key (KEY_FN) not recognized by XWindows
From: Dmitry Torokhov @ 2011-02-07 18:48 UTC (permalink / raw)
  To: Rakesh Iyer; +Cc: linux-input@vger.kernel.org
In-Reply-To: <1FC56210173BB445BD77F608D6FB8D03165A0080B0@HQMAIL03.nvidia.com>

Hi Rakesh,

On Fri, Feb 04, 2011 at 05:05:50PM -0800, Rakesh Iyer wrote:
> Hi All.
> 
> I am writing a Keyboard driver where the Function key (as seen in Laptop) is used as a modifier.
> In my driver I have used "KEY_FN"(from include/linux/input.h) as the keycode for this key.
> 
> When I run "xev" the key press events do not get detected.
> If I modify the keycode to say KEY_MEDIA, "xev" does show the event properly.
> 
> I am wondering how to go about getting this key detected and processed by XWindows.

Yes, indeed, you are stumbling against limitation of X which does not
allow to pass keycodes above 255 through it.

One option would be assigning KEY_LEFTMETA or KEY_RIGHTMETA to your 'Fn'
key and then adjusting keymaps, but after I looked again at the keys you
have assigned by default to your Fn combinations  can see how one would
want to avoid involving X's keymaps and be able to generate needed
keycodes directly (volume, brightness and other control events) so that
infrastructure need not be hooked into X to be able to react to them.

I think if you implement a hard/soft-fn flag in platform data and, in
case of hard_fn mode would suppress KEY_FN event but rather treat it as
most significant bit in your row data (effectively doubling keymap size)
that would solve your issue.

What do you think?

Thanks.

-- 
Dmitry

^ permalink raw reply

* Jitter Due to Large Number of Timers
From: Peter LaDow @ 2011-02-07 18:48 UTC (permalink / raw)
  To: linux-rt-users

We are measure large amounts of jitter on our PPC platform when there
are a large number of hrtimers.  This jitter is present regardless of
the priority of the tasks that depend upon those timers, and higher
(indeed the highest) priority tasks exhibit large jitter.  We've
created some test code for measuring this jitter and could really use
some insight from the RT experts here.  Here's our test setup.

We have a small C program that has a calibrated while loop that takes
approximately 4ms to execute.  For example, on our platform, it takes
just about 4ms to execute (call this 'test1'):

  float val = 1.234;

  for(i=0; i < 100000; i++)
  {
    val *= 12.354;
  }

We call clock_gettime() before and after this loop, then measure the
difference.  When running on a system with few hrtimers (about 6), we
get just about 4ms.  The problem appears when we add other
processes/threads that make use of hrtimers.  To test this, we created
another test program (call this 'test100') that creates 100 threads,
and each call clock_nanosleep() with a 4ms timeout.  When the number
of hrtimers spike, all with close expiration, the jitter on 'test1'
exceeds 400us, about 10%.  We run 'test1' with SCHED_FIFO at priority
99, and 'test100' under the default scheduler.  Here's some results:

Baseline:
  test100 not running
  /proc/timer_list showing 9 timers
  test1 run as 'chrt -f 99 ./test'

  Average: 3.817ms, Maximum: 3.859ms, Minimum: 3.809ms

Under load:
  test100 running as './test100'
  test1 run as 'chrt -f 99 ./test'

  Average: 4.168ms, Maximum: 4.204ms, Minimum: 3.585ms

We see a spike of 387us from the average (3.817ms baseline to 4.204ms
maximum).  And it is worse in our real system, since these other tasks
are also running as SCHED_FIFO.  This is problematic for our system,
because our highest priority task must complete in a fixed minimum
time.  But when these other tasks (all of which use clock_nanosleep()
or nanosleep()) are running, the excessive jitter breaks things.

Now, we supposed our highest priority task would not be interrupted by
lower priority tasks.  And indeed, they don't seem to be.  However, it
seems that the processing of a large number of hrtimers by the kernel
is starving our task of time.  How the hrtimers are implemented, and
how the kernel reacts to multiple timers expiring (or have expired)
isn't clear to us.

Any insight on the source of this jitter, and how to solve it would be
greatly appreciated.  We are running 2.6.29.3-rt13, but we have tried
it on 2.6.33.7.2-rt30.  Or platform is a MPC8349 at 533MHz.

Thanks,
Pete LaDow

^ permalink raw reply

* Re: [PATCH/RFC] commit: fix memory-leak
From: Matthieu Moy @ 2011-02-07 18:48 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: git, msysgit, blees
In-Reply-To: <1297104044-4684-1-git-send-email-kusmabite@gmail.com>

Erik Faye-Lund <kusmabite@gmail.com> writes:

> At the same time, this fixes a problem with strict-POSIX getenv
> implementations. POSIX says "The return value from getenv() may
> point to static data which may be overwritten by subsequent calls
> to getenv()", so duplicating the strings is a potential bug.
                  ^
                 not
?

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Local copy of the repository files
From: Roberto @ 2011-02-07 18:46 UTC (permalink / raw)
  To: git

Hi,

I'm trying to make my git repository automatically make a local copy o f 
the repository files, but the appropriate command (or commands) is 
eluding me. Could somebody give me a hint (or point to the appropriate 
document) as of how to make it work?

In more details, what I need:

When one of our developers does commit/push his work to the 
server/repository, I need the files to be automatically copied/updated 
to a plain local folder (something like file://var/www/), so they are 
viewable through a web browser. Most of those files are php. I don't 
need an additional repository accessible with WebDAV, HTTP, or something 
alike. Just a copy of the working files, viewable if someone opens a 
browser and types the URL of our server.

I did configure a "remote" server pointing to that folder (using  git 
remote add test file:///var/www/), and 'git fetch test' does give me the 
following output:
 From file:///var/www
    203a9c7..b47fab5  master     -> test/master

So probably it´s working correctly. But a "git remote push" is not 
updating that folder. Also, I believe that probably I'm supposed to use 
a hook (probably post-update), but can't find out what exactly I should 
add in there. Would appreciate any ideas here.

Note: I'm using Debian 5.0-64bits, git 1.5.6.5 (from the apt repository).

Thanks,

Roberto

-- 
   -----------------------------------------------------
                 Marcos Roberto Greiner

    Os otimistas acham que estamos no melhor dos mundos
     Os pessimistas tem medo de que isto seja verdade
                                   James Branch Cabell
   -----------------------------------------------------

^ permalink raw reply

* RE: [PATCH V8 03/10] USB/ppc4xx: Add Synopsys DWC OTG CoreInterface Layer
From: Tirumala Marri @ 2011-02-07 18:45 UTC (permalink / raw)
  To: David Laight; +Cc: linux-usb, linuxppc-dev
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6D8AC2C@saturn3.aculab.com>

-----Original Message-----
From: linuxppc-dev-bounces+tmarri=amcc.com@lists.ozlabs.org
[mailto:linuxppc-dev-bounces+tmarri=amcc.com@lists.ozlabs.org] On Behalf
Of David Laight
Sent: Wednesday, January 26, 2011 8:35 AM
Cc: linux-usb@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
Subject: RE: [PATCH V8 03/10] USB/ppc4xx: Add Synopsys DWC OTG
CoreInterface Layer


> Also in_le32/out_le32/in_be32/out_be32 are
> architecture-specific AFAIK.

Isn't the whole patch architecture-specific ?

> I'd suggest using readl/writel for LE ops and
> __be32_to_cpu(__raw_readl(addr))/__raw_writel(__cpu_to_be32(b),addr)
> for BE ops.

Since the ppc doesn't have a byteswap instruction (and the LE
memory transfers might even be slow!) you really don't want to
be doing software byteswap.

Not to mention the horrific synchronistion instructions
that in_le32() and out_le32() actually contain.

I didn't find __raw_readl() when I was looking for asm
patterns that byteswapped memory transfers.

I did find st_le32() and ld_le32() in arch/powerpc/include/asm/swab.h
but that file is actually quite difficult to #include because
there is another swab.h that gets included instead.

[marri] Initial version of DWC-IP did not have feature to swap endianness.
Whereas next versions have it.

^ permalink raw reply

* Re: [RFC] Split up mm/bootmem.c
From: Yinghai Lu @ 2011-02-07 18:45 UTC (permalink / raw)
  To: Namhyung Kim; +Cc: linux-mm, linux-kernel
In-Reply-To: <1297092614-1906-1-git-send-email-namhyung@gmail.com>

On Mon, Feb 7, 2011 at 7:30 AM, Namhyung Kim <namhyung@gmail.com> wrote:
> The bootmem code contained many #ifdefs in it so that it could be
> splitted into two files for the readability. The split was quite
> mechanical and only function need to be shared was free_bootmem_late.
>
> Tested on x86-64 and um which use nobootmem and bootmem respectively.
>
> Signed-off-by: Namhyung Kim <namhyung@gmail.com>


https://lkml.org/lkml/2010/6/16/44
...



> ---
>  mm/Makefile    |    8 +-
>  mm/bootmem.c   |  164 +--------------------
>  mm/nobootmem.c |  445 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 454 insertions(+), 163 deletions(-)
>  create mode 100644 mm/nobootmem.c
>
> diff --git a/mm/Makefile b/mm/Makefile
> index 2b1b575ae712..e9a074dbad15 100644
> --- a/mm/Makefile
> +++ b/mm/Makefile
> @@ -7,7 +7,7 @@ mmu-$(CONFIG_MMU)       := fremap.o highmem.o madvise.o memory.o mincore.o \
>                           mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \
>                           vmalloc.o pagewalk.o pgtable-generic.o
>
> -obj-y                  := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
> +obj-y                  := filemap.o mempool.o oom_kill.o fadvise.o \
>                           maccess.o page_alloc.o page-writeback.o \
>                           readahead.o swap.o truncate.o vmscan.o shmem.o \
>                           prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
> @@ -15,6 +15,12 @@ obj-y                        := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
>                           $(mmu-y)
>  obj-y += init-mm.o
>
> +ifeq ($(CONFIG_NO_BOOTMEM),y)
> +obj-y += nobootmem.o
> +else
> +obj-y += bootmem.o
> +endif
> +
>  obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o
>
>  obj-$(CONFIG_BOUNCE)   += bounce.o
> diff --git a/mm/bootmem.c b/mm/bootmem.c
> index 13b0caa9793c..209be265ad94 100644
> --- a/mm/bootmem.c
> +++ b/mm/bootmem.c
> @@ -35,7 +35,6 @@ unsigned long max_pfn;
>  unsigned long saved_max_pfn;
>  #endif
>
> -#ifndef CONFIG_NO_BOOTMEM
>  bootmem_data_t bootmem_node_data[MAX_NUMNODES] __initdata;
>
>  static struct list_head bdata_list __initdata = LIST_HEAD_INIT(bdata_list);
> @@ -146,8 +145,8 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
>        min_low_pfn = start;
>        return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages);
>  }
> -#endif
> -/*
> +
> +/**
>  * free_bootmem_late - free bootmem pages directly to page allocator
>  * @addr: starting address of the range
>  * @size: size of the range in bytes
> @@ -171,53 +170,6 @@ void __init free_bootmem_late(unsigned long addr, unsigned long size)
>        }
>  }
>
> -#ifdef CONFIG_NO_BOOTMEM
> -static void __init __free_pages_memory(unsigned long start, unsigned long end)
> -{
> -       int i;
> -       unsigned long start_aligned, end_aligned;
> -       int order = ilog2(BITS_PER_LONG);
> -
> -       start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
> -       end_aligned = end & ~(BITS_PER_LONG - 1);
> -
> -       if (end_aligned <= start_aligned) {
> -               for (i = start; i < end; i++)
> -                       __free_pages_bootmem(pfn_to_page(i), 0);
> -
> -               return;
> -       }
> -
> -       for (i = start; i < start_aligned; i++)
> -               __free_pages_bootmem(pfn_to_page(i), 0);
> -
> -       for (i = start_aligned; i < end_aligned; i += BITS_PER_LONG)
> -               __free_pages_bootmem(pfn_to_page(i), order);
> -
> -       for (i = end_aligned; i < end; i++)
> -               __free_pages_bootmem(pfn_to_page(i), 0);
> -}
> -
> -unsigned long __init free_all_memory_core_early(int nodeid)
> -{
> -       int i;
> -       u64 start, end;
> -       unsigned long count = 0;
> -       struct range *range = NULL;
> -       int nr_range;
> -
> -       nr_range = get_free_all_memory_range(&range, nodeid);
> -
> -       for (i = 0; i < nr_range; i++) {
> -               start = range[i].start;
> -               end = range[i].end;
> -               count += end - start;
> -               __free_pages_memory(start, end);
> -       }
> -
> -       return count;
> -}
> -#else
>  static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
>  {
>        int aligned;
> @@ -278,7 +230,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
>
>        return count;
>  }
> -#endif
>
>  /**
>  * free_all_bootmem_node - release a node's free pages to the buddy allocator
> @@ -289,12 +240,7 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
>  unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
>  {
>        register_page_bootmem_info_node(pgdat);
> -#ifdef CONFIG_NO_BOOTMEM
> -       /* free_all_memory_core_early(MAX_NUMNODES) will be called later */
> -       return 0;
> -#else
>        return free_all_bootmem_core(pgdat->bdata);
> -#endif
>  }
>
>  /**
> @@ -304,16 +250,6 @@ unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
>  */
>  unsigned long __init free_all_bootmem(void)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       /*
> -        * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
> -        *  because in some case like Node0 doesnt have RAM installed
> -        *  low ram will be on Node1
> -        * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
> -        *  will be used instead of only Node0 related
> -        */
> -       return free_all_memory_core_early(MAX_NUMNODES);
> -#else
>        unsigned long total_pages = 0;
>        bootmem_data_t *bdata;
>
> @@ -321,10 +257,8 @@ unsigned long __init free_all_bootmem(void)
>                total_pages += free_all_bootmem_core(bdata);
>
>        return total_pages;
> -#endif
>  }
>
> -#ifndef CONFIG_NO_BOOTMEM
>  static void __init __free(bootmem_data_t *bdata,
>                        unsigned long sidx, unsigned long eidx)
>  {
> @@ -419,7 +353,6 @@ static int __init mark_bootmem(unsigned long start, unsigned long end,
>        }
>        BUG();
>  }
> -#endif
>
>  /**
>  * free_bootmem_node - mark a page range as usable
> @@ -434,10 +367,6 @@ static int __init mark_bootmem(unsigned long start, unsigned long end,
>  void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>                              unsigned long size)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       kmemleak_free_part(__va(physaddr), size);
> -       memblock_x86_free_range(physaddr, physaddr + size);
> -#else
>        unsigned long start, end;
>
>        kmemleak_free_part(__va(physaddr), size);
> @@ -446,7 +375,6 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>        end = PFN_DOWN(physaddr + size);
>
>        mark_bootmem_node(pgdat->bdata, start, end, 0, 0);
> -#endif
>  }
>
>  /**
> @@ -460,10 +388,6 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>  */
>  void __init free_bootmem(unsigned long addr, unsigned long size)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       kmemleak_free_part(__va(addr), size);
> -       memblock_x86_free_range(addr, addr + size);
> -#else
>        unsigned long start, end;
>
>        kmemleak_free_part(__va(addr), size);
> @@ -472,7 +396,6 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
>        end = PFN_DOWN(addr + size);
>
>        mark_bootmem(start, end, 0, 0);
> -#endif
>  }
>
>  /**
> @@ -489,17 +412,12 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
>  int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>                                 unsigned long size, int flags)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       panic("no bootmem");
> -       return 0;
> -#else
>        unsigned long start, end;
>
>        start = PFN_DOWN(physaddr);
>        end = PFN_UP(physaddr + size);
>
>        return mark_bootmem_node(pgdat->bdata, start, end, 1, flags);
> -#endif
>  }
>
>  /**
> @@ -515,20 +433,14 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>  int __init reserve_bootmem(unsigned long addr, unsigned long size,
>                            int flags)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       panic("no bootmem");
> -       return 0;
> -#else
>        unsigned long start, end;
>
>        start = PFN_DOWN(addr);
>        end = PFN_UP(addr + size);
>
>        return mark_bootmem(start, end, 1, flags);
> -#endif
>  }
>
> -#ifndef CONFIG_NO_BOOTMEM
>  int __weak __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
>                                   int flags)
>  {
> @@ -685,33 +597,12 @@ static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata,
>  #endif
>        return NULL;
>  }
> -#endif
>
>  static void * __init ___alloc_bootmem_nopanic(unsigned long size,
>                                        unsigned long align,
>                                        unsigned long goal,
>                                        unsigned long limit)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       void *ptr;
> -
> -       if (WARN_ON_ONCE(slab_is_available()))
> -               return kzalloc(size, GFP_NOWAIT);
> -
> -restart:
> -
> -       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, goal, limit);
> -
> -       if (ptr)
> -               return ptr;
> -
> -       if (goal != 0) {
> -               goal = 0;
> -               goto restart;
> -       }
> -
> -       return NULL;
> -#else
>        bootmem_data_t *bdata;
>        void *region;
>
> @@ -737,7 +628,6 @@ restart:
>        }
>
>        return NULL;
> -#endif
>  }
>
>  /**
> @@ -758,10 +648,6 @@ void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
>  {
>        unsigned long limit = 0;
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       limit = -1UL;
> -#endif
> -
>        return ___alloc_bootmem_nopanic(size, align, goal, limit);
>  }
>
> @@ -798,14 +684,9 @@ void * __init __alloc_bootmem(unsigned long size, unsigned long align,
>  {
>        unsigned long limit = 0;
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       limit = -1UL;
> -#endif
> -
>        return ___alloc_bootmem(size, align, goal, limit);
>  }
>
> -#ifndef CONFIG_NO_BOOTMEM
>  static void * __init ___alloc_bootmem_node(bootmem_data_t *bdata,
>                                unsigned long size, unsigned long align,
>                                unsigned long goal, unsigned long limit)
> @@ -822,7 +703,6 @@ static void * __init ___alloc_bootmem_node(bootmem_data_t *bdata,
>
>        return ___alloc_bootmem(size, align, goal, limit);
>  }
> -#endif
>
>  /**
>  * __alloc_bootmem_node - allocate boot memory from a specific node
> @@ -847,17 +727,7 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
>        if (WARN_ON_ONCE(slab_is_available()))
>                return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> -                                        goal, -1ULL);
> -       if (ptr)
> -               return ptr;
> -
> -       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> -                                        goal, -1ULL);
> -#else
>        ptr = ___alloc_bootmem_node(pgdat->bdata, size, align, goal, 0);
> -#endif
>
>        return ptr;
>  }
> @@ -880,13 +750,8 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
>                unsigned long new_goal;
>
>                new_goal = MAX_DMA32_PFN << PAGE_SHIFT;
> -#ifdef CONFIG_NO_BOOTMEM
> -               ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> -                                                new_goal, -1ULL);
> -#else
>                ptr = alloc_bootmem_core(pgdat->bdata, size, align,
>                                                 new_goal, 0);
> -#endif
>                if (ptr)
>                        return ptr;
>        }
> @@ -907,16 +772,6 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
>  void * __init alloc_bootmem_section(unsigned long size,
>                                    unsigned long section_nr)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       unsigned long pfn, goal, limit;
> -
> -       pfn = section_nr_to_pfn(section_nr);
> -       goal = pfn << PAGE_SHIFT;
> -       limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT;
> -
> -       return __alloc_memory_core_early(early_pfn_to_nid(pfn), size,
> -                                        SMP_CACHE_BYTES, goal, limit);
> -#else
>        bootmem_data_t *bdata;
>        unsigned long pfn, goal, limit;
>
> @@ -926,7 +781,6 @@ void * __init alloc_bootmem_section(unsigned long size,
>        bdata = &bootmem_node_data[early_pfn_to_nid(pfn)];
>
>        return alloc_bootmem_core(bdata, size, SMP_CACHE_BYTES, goal, limit);
> -#endif
>  }
>  #endif
>
> @@ -938,16 +792,11 @@ void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
>        if (WARN_ON_ONCE(slab_is_available()))
>                return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> -                                                goal, -1ULL);
> -#else
>        ptr = alloc_arch_preferred_bootmem(pgdat->bdata, size, align, goal, 0);
>        if (ptr)
>                return ptr;
>
>        ptr = alloc_bootmem_core(pgdat->bdata, size, align, goal, 0);
> -#endif
>        if (ptr)
>                return ptr;
>
> @@ -1000,16 +849,7 @@ void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
>        if (WARN_ON_ONCE(slab_is_available()))
>                return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> -                               goal, ARCH_LOW_ADDRESS_LIMIT);
> -       if (ptr)
> -               return ptr;
> -       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> -                               goal, ARCH_LOW_ADDRESS_LIMIT);
> -#else
>        ptr = ___alloc_bootmem_node(pgdat->bdata, size, align,
>                                goal, ARCH_LOW_ADDRESS_LIMIT);
> -#endif
>        return ptr;
>  }
> diff --git a/mm/nobootmem.c b/mm/nobootmem.c
> new file mode 100644
> index 000000000000..e93c3475011b
> --- /dev/null
> +++ b/mm/nobootmem.c
> @@ -0,0 +1,445 @@
> +/*
> + *  nobootmem - A boot-time physical memory allocator and configurator
> + *
> + *  Copyright (C) 1999 Ingo Molnar
> + *                1999 Kanoj Sarcar, SGI
> + *                2008 Johannes Weiner
> + *
> + *  Split out of bootmem.c by Namhyung Kim <namhyung@gmail.com>
> + *
> + * Access to this subsystem has to be serialized externally (which is true
> + * for the boot process anyway).
> + */
> +#include <linux/init.h>
> +#include <linux/pfn.h>
> +#include <linux/slab.h>
> +#include <linux/bootmem.h>
> +#include <linux/module.h>
> +#include <linux/kmemleak.h>
> +#include <linux/range.h>
> +#include <linux/memblock.h>
> +
> +#include <asm/bug.h>
> +#include <asm/io.h>
> +#include <asm/processor.h>
> +
> +#include "internal.h"
> +
> +unsigned long max_low_pfn;
> +unsigned long min_low_pfn;
> +unsigned long max_pfn;
> +
> +#ifdef CONFIG_CRASH_DUMP
> +/*
> + * If we have booted due to a crash, max_pfn will be a very low value. We need
> + * to know the amount of memory that the previous kernel used.
> + */
> +unsigned long saved_max_pfn;
> +#endif
> +
> +/**
> + * free_bootmem_late - free bootmem pages directly to page allocator
> + * @addr: starting address of the range
> + * @size: size of the range in bytes
> + *
> + * This is only useful when the bootmem allocator has already been torn
> + * down, but we are still initializing the system.  Pages are given directly
> + * to the page allocator, no bootmem metadata is updated because it is gone.
> + */
> +void __init free_bootmem_late(unsigned long addr, unsigned long size)
> +{
> +       unsigned long cursor, end;
> +
> +       kmemleak_free_part(__va(addr), size);
> +
> +       cursor = PFN_UP(addr);
> +       end = PFN_DOWN(addr + size);
> +
> +       for (; cursor < end; cursor++) {
> +               __free_pages_bootmem(pfn_to_page(cursor), 0);
> +               totalram_pages++;
> +       }
> +}
> +
> +static void __init __free_pages_memory(unsigned long start, unsigned long end)
> +{
> +       int i;
> +       unsigned long start_aligned, end_aligned;
> +       int order = ilog2(BITS_PER_LONG);
> +
> +       start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
> +       end_aligned = end & ~(BITS_PER_LONG - 1);
> +
> +       if (end_aligned <= start_aligned) {
> +               for (i = start; i < end; i++)
> +                       __free_pages_bootmem(pfn_to_page(i), 0);
> +
> +               return;
> +       }
> +
> +       for (i = start; i < start_aligned; i++)
> +               __free_pages_bootmem(pfn_to_page(i), 0);
> +
> +       for (i = start_aligned; i < end_aligned; i += BITS_PER_LONG)
> +               __free_pages_bootmem(pfn_to_page(i), order);
> +
> +       for (i = end_aligned; i < end; i++)
> +               __free_pages_bootmem(pfn_to_page(i), 0);
> +}
> +
> +unsigned long __init free_all_memory_core_early(int nodeid)
> +{
> +       int i;
> +       u64 start, end;
> +       unsigned long count = 0;
> +       struct range *range = NULL;
> +       int nr_range;
> +
> +       nr_range = get_free_all_memory_range(&range, nodeid);
> +
> +       for (i = 0; i < nr_range; i++) {
> +               start = range[i].start;
> +               end = range[i].end;
> +               count += end - start;
> +               __free_pages_memory(start, end);
> +       }
> +
> +       return count;
> +}
> +
> +/**
> + * free_all_bootmem_node - release a node's free pages to the buddy allocator
> + * @pgdat: node to be released
> + *
> + * Returns the number of pages actually released.
> + */
> +unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
> +{
> +       register_page_bootmem_info_node(pgdat);
> +
> +       /* free_all_memory_core_early(MAX_NUMNODES) will be called later */
> +       return 0;
> +}
> +
> +/**
> + * free_all_bootmem - release free pages to the buddy allocator
> + *
> + * Returns the number of pages actually released.
> + */
> +unsigned long __init free_all_bootmem(void)
> +{
> +       /*
> +        * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
> +        *  because in some case like Node0 doesnt have RAM installed
> +        *  low ram will be on Node1
> +        * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
> +        *  will be used instead of only Node0 related
> +        */
> +       return free_all_memory_core_early(MAX_NUMNODES);
> +}
> +
> +/**
> + * free_bootmem_node - mark a page range as usable
> + * @pgdat: node the range resides on
> + * @physaddr: starting address of the range
> + * @size: size of the range in bytes
> + *
> + * Partial pages will be considered reserved and left as they are.
> + *
> + * The range must reside completely on the specified node.
> + */
> +void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
> +                             unsigned long size)
> +{
> +       kmemleak_free_part(__va(physaddr), size);
> +       memblock_x86_free_range(physaddr, physaddr + size);
> +}
> +
> +/**
> + * free_bootmem - mark a page range as usable
> + * @addr: starting address of the range
> + * @size: size of the range in bytes
> + *
> + * Partial pages will be considered reserved and left as they are.
> + *
> + * The range must be contiguous but may span node boundaries.
> + */
> +void __init free_bootmem(unsigned long addr, unsigned long size)
> +{
> +       kmemleak_free_part(__va(addr), size);
> +       memblock_x86_free_range(addr, addr + size);
> +}
> +
> +/**
> + * reserve_bootmem_node - mark a page range as reserved
> + * @pgdat: node the range resides on
> + * @physaddr: starting address of the range
> + * @size: size of the range in bytes
> + * @flags: reservation flags (see linux/bootmem.h)
> + *
> + * Partial pages will be reserved.
> + *
> + * The range must reside completely on the specified node.
> + */
> +int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
> +                                unsigned long size, int flags)
> +{
> +       panic("no bootmem");
> +       return 0;
> +}
> +
> +/**
> + * reserve_bootmem - mark a page range as usable
> + * @addr: starting address of the range
> + * @size: size of the range in bytes
> + * @flags: reservation flags (see linux/bootmem.h)
> + *
> + * Partial pages will be reserved.
> + *
> + * The range must be contiguous but may span node boundaries.
> + */
> +int __init reserve_bootmem(unsigned long addr, unsigned long size,
> +                           int flags)
> +{
> +       panic("no bootmem");
> +       return 0;
> +}
> +
> +static void * __init ___alloc_bootmem_nopanic(unsigned long size,
> +                                       unsigned long align,
> +                                       unsigned long goal,
> +                                       unsigned long limit)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc(size, GFP_NOWAIT);
> +
> +restart:
> +
> +       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, goal, limit);
> +
> +       if (ptr)
> +               return ptr;
> +
> +       if (goal != 0) {
> +               goal = 0;
> +               goto restart;
> +       }
> +
> +       return NULL;
> +}
> +
> +/**
> + * __alloc_bootmem_nopanic - allocate boot memory without panicking
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may happen on any node in the system.
> + *
> + * Returns NULL on failure.
> + */
> +void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
> +                                       unsigned long goal)
> +{
> +       unsigned long limit = -1UL;
> +
> +       return ___alloc_bootmem_nopanic(size, align, goal, limit);
> +}
> +
> +static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
> +                                       unsigned long goal, unsigned long limit)
> +{
> +       void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
> +
> +       if (mem)
> +               return mem;
> +       /*
> +        * Whoops, we cannot satisfy the allocation request.
> +        */
> +       printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
> +       panic("Out of memory");
> +       return NULL;
> +}
> +
> +/**
> + * __alloc_bootmem - allocate boot memory
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may happen on any node in the system.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem(unsigned long size, unsigned long align,
> +                             unsigned long goal)
> +{
> +       unsigned long limit = -1UL;
> +
> +       return ___alloc_bootmem(size, align, goal, limit);
> +}
> +
> +/**
> + * __alloc_bootmem_node - allocate boot memory from a specific node
> + * @pgdat: node to allocate from
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may fall back to any node in the system if the specified node
> + * can not hold the requested memory.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
> +                                  unsigned long align, unsigned long goal)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> +                                        goal, -1ULL);
> +       if (ptr)
> +               return ptr;
> +
> +       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> +                                        goal, -1ULL);
> +
> +       return ptr;
> +}
> +
> +void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
> +                                  unsigned long align, unsigned long goal)
> +{
> +#ifdef MAX_DMA32_PFN
> +       unsigned long end_pfn;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       /* update goal according ...MAX_DMA32_PFN */
> +       end_pfn = pgdat->node_start_pfn + pgdat->node_spanned_pages;
> +
> +       if (end_pfn > MAX_DMA32_PFN + (128 >> (20 - PAGE_SHIFT)) &&
> +           (goal >> PAGE_SHIFT) < MAX_DMA32_PFN) {
> +               void *ptr;
> +               unsigned long new_goal;
> +
> +               new_goal = MAX_DMA32_PFN << PAGE_SHIFT;
> +               ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> +                                                new_goal, -1ULL);
> +               if (ptr)
> +                       return ptr;
> +       }
> +#endif
> +
> +       return __alloc_bootmem_node(pgdat, size, align, goal);
> +
> +}
> +
> +#ifdef CONFIG_SPARSEMEM
> +/**
> + * alloc_bootmem_section - allocate boot memory from a specific section
> + * @size: size of the request in bytes
> + * @section_nr: sparse map section to allocate from
> + *
> + * Return NULL on failure.
> + */
> +void * __init alloc_bootmem_section(unsigned long size,
> +                                   unsigned long section_nr)
> +{
> +       unsigned long pfn, goal, limit;
> +
> +       pfn = section_nr_to_pfn(section_nr);
> +       goal = pfn << PAGE_SHIFT;
> +       limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT;
> +
> +       return __alloc_memory_core_early(early_pfn_to_nid(pfn), size,
> +                                        SMP_CACHE_BYTES, goal, limit);
> +}
> +#endif
> +
> +void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
> +                                  unsigned long align, unsigned long goal)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> +                                                goal, -1ULL);
> +       if (ptr)
> +               return ptr;
> +
> +       return __alloc_bootmem_nopanic(size, align, goal);
> +}
> +
> +#ifndef ARCH_LOW_ADDRESS_LIMIT
> +#define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL
> +#endif
> +
> +/**
> + * __alloc_bootmem_low - allocate low boot memory
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may happen on any node in the system.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
> +                                 unsigned long goal)
> +{
> +       return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
> +}
> +
> +/**
> + * __alloc_bootmem_low_node - allocate low boot memory from a specific node
> + * @pgdat: node to allocate from
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may fall back to any node in the system if the specified node
> + * can not hold the requested memory.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
> +                                      unsigned long align, unsigned long goal)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> +                               goal, ARCH_LOW_ADDRESS_LIMIT);
> +       if (ptr)
> +               return ptr;
> +
> +       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> +                               goal, ARCH_LOW_ADDRESS_LIMIT);
> +       return ptr;
> +}
> --
> 1.7.3.4.600.g982838b0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [RFC] Split up mm/bootmem.c
From: Yinghai Lu @ 2011-02-07 18:45 UTC (permalink / raw)
  To: Namhyung Kim; +Cc: linux-mm, linux-kernel
In-Reply-To: <1297092614-1906-1-git-send-email-namhyung@gmail.com>

On Mon, Feb 7, 2011 at 7:30 AM, Namhyung Kim <namhyung@gmail.com> wrote:
> The bootmem code contained many #ifdefs in it so that it could be
> splitted into two files for the readability. The split was quite
> mechanical and only function need to be shared was free_bootmem_late.
>
> Tested on x86-64 and um which use nobootmem and bootmem respectively.
>
> Signed-off-by: Namhyung Kim <namhyung@gmail.com>


https://lkml.org/lkml/2010/6/16/44
...



> ---
>  mm/Makefile    |    8 +-
>  mm/bootmem.c   |  164 +--------------------
>  mm/nobootmem.c |  445 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 454 insertions(+), 163 deletions(-)
>  create mode 100644 mm/nobootmem.c
>
> diff --git a/mm/Makefile b/mm/Makefile
> index 2b1b575ae712..e9a074dbad15 100644
> --- a/mm/Makefile
> +++ b/mm/Makefile
> @@ -7,7 +7,7 @@ mmu-$(CONFIG_MMU)       := fremap.o highmem.o madvise.o memory.o mincore.o \
>                           mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \
>                           vmalloc.o pagewalk.o pgtable-generic.o
>
> -obj-y                  := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
> +obj-y                  := filemap.o mempool.o oom_kill.o fadvise.o \
>                           maccess.o page_alloc.o page-writeback.o \
>                           readahead.o swap.o truncate.o vmscan.o shmem.o \
>                           prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
> @@ -15,6 +15,12 @@ obj-y                        := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
>                           $(mmu-y)
>  obj-y += init-mm.o
>
> +ifeq ($(CONFIG_NO_BOOTMEM),y)
> +obj-y += nobootmem.o
> +else
> +obj-y += bootmem.o
> +endif
> +
>  obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o
>
>  obj-$(CONFIG_BOUNCE)   += bounce.o
> diff --git a/mm/bootmem.c b/mm/bootmem.c
> index 13b0caa9793c..209be265ad94 100644
> --- a/mm/bootmem.c
> +++ b/mm/bootmem.c
> @@ -35,7 +35,6 @@ unsigned long max_pfn;
>  unsigned long saved_max_pfn;
>  #endif
>
> -#ifndef CONFIG_NO_BOOTMEM
>  bootmem_data_t bootmem_node_data[MAX_NUMNODES] __initdata;
>
>  static struct list_head bdata_list __initdata = LIST_HEAD_INIT(bdata_list);
> @@ -146,8 +145,8 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
>        min_low_pfn = start;
>        return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages);
>  }
> -#endif
> -/*
> +
> +/**
>  * free_bootmem_late - free bootmem pages directly to page allocator
>  * @addr: starting address of the range
>  * @size: size of the range in bytes
> @@ -171,53 +170,6 @@ void __init free_bootmem_late(unsigned long addr, unsigned long size)
>        }
>  }
>
> -#ifdef CONFIG_NO_BOOTMEM
> -static void __init __free_pages_memory(unsigned long start, unsigned long end)
> -{
> -       int i;
> -       unsigned long start_aligned, end_aligned;
> -       int order = ilog2(BITS_PER_LONG);
> -
> -       start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
> -       end_aligned = end & ~(BITS_PER_LONG - 1);
> -
> -       if (end_aligned <= start_aligned) {
> -               for (i = start; i < end; i++)
> -                       __free_pages_bootmem(pfn_to_page(i), 0);
> -
> -               return;
> -       }
> -
> -       for (i = start; i < start_aligned; i++)
> -               __free_pages_bootmem(pfn_to_page(i), 0);
> -
> -       for (i = start_aligned; i < end_aligned; i += BITS_PER_LONG)
> -               __free_pages_bootmem(pfn_to_page(i), order);
> -
> -       for (i = end_aligned; i < end; i++)
> -               __free_pages_bootmem(pfn_to_page(i), 0);
> -}
> -
> -unsigned long __init free_all_memory_core_early(int nodeid)
> -{
> -       int i;
> -       u64 start, end;
> -       unsigned long count = 0;
> -       struct range *range = NULL;
> -       int nr_range;
> -
> -       nr_range = get_free_all_memory_range(&range, nodeid);
> -
> -       for (i = 0; i < nr_range; i++) {
> -               start = range[i].start;
> -               end = range[i].end;
> -               count += end - start;
> -               __free_pages_memory(start, end);
> -       }
> -
> -       return count;
> -}
> -#else
>  static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
>  {
>        int aligned;
> @@ -278,7 +230,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
>
>        return count;
>  }
> -#endif
>
>  /**
>  * free_all_bootmem_node - release a node's free pages to the buddy allocator
> @@ -289,12 +240,7 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
>  unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
>  {
>        register_page_bootmem_info_node(pgdat);
> -#ifdef CONFIG_NO_BOOTMEM
> -       /* free_all_memory_core_early(MAX_NUMNODES) will be called later */
> -       return 0;
> -#else
>        return free_all_bootmem_core(pgdat->bdata);
> -#endif
>  }
>
>  /**
> @@ -304,16 +250,6 @@ unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
>  */
>  unsigned long __init free_all_bootmem(void)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       /*
> -        * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
> -        *  because in some case like Node0 doesnt have RAM installed
> -        *  low ram will be on Node1
> -        * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
> -        *  will be used instead of only Node0 related
> -        */
> -       return free_all_memory_core_early(MAX_NUMNODES);
> -#else
>        unsigned long total_pages = 0;
>        bootmem_data_t *bdata;
>
> @@ -321,10 +257,8 @@ unsigned long __init free_all_bootmem(void)
>                total_pages += free_all_bootmem_core(bdata);
>
>        return total_pages;
> -#endif
>  }
>
> -#ifndef CONFIG_NO_BOOTMEM
>  static void __init __free(bootmem_data_t *bdata,
>                        unsigned long sidx, unsigned long eidx)
>  {
> @@ -419,7 +353,6 @@ static int __init mark_bootmem(unsigned long start, unsigned long end,
>        }
>        BUG();
>  }
> -#endif
>
>  /**
>  * free_bootmem_node - mark a page range as usable
> @@ -434,10 +367,6 @@ static int __init mark_bootmem(unsigned long start, unsigned long end,
>  void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>                              unsigned long size)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       kmemleak_free_part(__va(physaddr), size);
> -       memblock_x86_free_range(physaddr, physaddr + size);
> -#else
>        unsigned long start, end;
>
>        kmemleak_free_part(__va(physaddr), size);
> @@ -446,7 +375,6 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>        end = PFN_DOWN(physaddr + size);
>
>        mark_bootmem_node(pgdat->bdata, start, end, 0, 0);
> -#endif
>  }
>
>  /**
> @@ -460,10 +388,6 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>  */
>  void __init free_bootmem(unsigned long addr, unsigned long size)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       kmemleak_free_part(__va(addr), size);
> -       memblock_x86_free_range(addr, addr + size);
> -#else
>        unsigned long start, end;
>
>        kmemleak_free_part(__va(addr), size);
> @@ -472,7 +396,6 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
>        end = PFN_DOWN(addr + size);
>
>        mark_bootmem(start, end, 0, 0);
> -#endif
>  }
>
>  /**
> @@ -489,17 +412,12 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
>  int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>                                 unsigned long size, int flags)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       panic("no bootmem");
> -       return 0;
> -#else
>        unsigned long start, end;
>
>        start = PFN_DOWN(physaddr);
>        end = PFN_UP(physaddr + size);
>
>        return mark_bootmem_node(pgdat->bdata, start, end, 1, flags);
> -#endif
>  }
>
>  /**
> @@ -515,20 +433,14 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
>  int __init reserve_bootmem(unsigned long addr, unsigned long size,
>                            int flags)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       panic("no bootmem");
> -       return 0;
> -#else
>        unsigned long start, end;
>
>        start = PFN_DOWN(addr);
>        end = PFN_UP(addr + size);
>
>        return mark_bootmem(start, end, 1, flags);
> -#endif
>  }
>
> -#ifndef CONFIG_NO_BOOTMEM
>  int __weak __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
>                                   int flags)
>  {
> @@ -685,33 +597,12 @@ static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata,
>  #endif
>        return NULL;
>  }
> -#endif
>
>  static void * __init ___alloc_bootmem_nopanic(unsigned long size,
>                                        unsigned long align,
>                                        unsigned long goal,
>                                        unsigned long limit)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       void *ptr;
> -
> -       if (WARN_ON_ONCE(slab_is_available()))
> -               return kzalloc(size, GFP_NOWAIT);
> -
> -restart:
> -
> -       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, goal, limit);
> -
> -       if (ptr)
> -               return ptr;
> -
> -       if (goal != 0) {
> -               goal = 0;
> -               goto restart;
> -       }
> -
> -       return NULL;
> -#else
>        bootmem_data_t *bdata;
>        void *region;
>
> @@ -737,7 +628,6 @@ restart:
>        }
>
>        return NULL;
> -#endif
>  }
>
>  /**
> @@ -758,10 +648,6 @@ void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
>  {
>        unsigned long limit = 0;
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       limit = -1UL;
> -#endif
> -
>        return ___alloc_bootmem_nopanic(size, align, goal, limit);
>  }
>
> @@ -798,14 +684,9 @@ void * __init __alloc_bootmem(unsigned long size, unsigned long align,
>  {
>        unsigned long limit = 0;
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       limit = -1UL;
> -#endif
> -
>        return ___alloc_bootmem(size, align, goal, limit);
>  }
>
> -#ifndef CONFIG_NO_BOOTMEM
>  static void * __init ___alloc_bootmem_node(bootmem_data_t *bdata,
>                                unsigned long size, unsigned long align,
>                                unsigned long goal, unsigned long limit)
> @@ -822,7 +703,6 @@ static void * __init ___alloc_bootmem_node(bootmem_data_t *bdata,
>
>        return ___alloc_bootmem(size, align, goal, limit);
>  }
> -#endif
>
>  /**
>  * __alloc_bootmem_node - allocate boot memory from a specific node
> @@ -847,17 +727,7 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
>        if (WARN_ON_ONCE(slab_is_available()))
>                return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> -                                        goal, -1ULL);
> -       if (ptr)
> -               return ptr;
> -
> -       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> -                                        goal, -1ULL);
> -#else
>        ptr = ___alloc_bootmem_node(pgdat->bdata, size, align, goal, 0);
> -#endif
>
>        return ptr;
>  }
> @@ -880,13 +750,8 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
>                unsigned long new_goal;
>
>                new_goal = MAX_DMA32_PFN << PAGE_SHIFT;
> -#ifdef CONFIG_NO_BOOTMEM
> -               ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> -                                                new_goal, -1ULL);
> -#else
>                ptr = alloc_bootmem_core(pgdat->bdata, size, align,
>                                                 new_goal, 0);
> -#endif
>                if (ptr)
>                        return ptr;
>        }
> @@ -907,16 +772,6 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
>  void * __init alloc_bootmem_section(unsigned long size,
>                                    unsigned long section_nr)
>  {
> -#ifdef CONFIG_NO_BOOTMEM
> -       unsigned long pfn, goal, limit;
> -
> -       pfn = section_nr_to_pfn(section_nr);
> -       goal = pfn << PAGE_SHIFT;
> -       limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT;
> -
> -       return __alloc_memory_core_early(early_pfn_to_nid(pfn), size,
> -                                        SMP_CACHE_BYTES, goal, limit);
> -#else
>        bootmem_data_t *bdata;
>        unsigned long pfn, goal, limit;
>
> @@ -926,7 +781,6 @@ void * __init alloc_bootmem_section(unsigned long size,
>        bdata = &bootmem_node_data[early_pfn_to_nid(pfn)];
>
>        return alloc_bootmem_core(bdata, size, SMP_CACHE_BYTES, goal, limit);
> -#endif
>  }
>  #endif
>
> @@ -938,16 +792,11 @@ void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
>        if (WARN_ON_ONCE(slab_is_available()))
>                return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> -                                                goal, -1ULL);
> -#else
>        ptr = alloc_arch_preferred_bootmem(pgdat->bdata, size, align, goal, 0);
>        if (ptr)
>                return ptr;
>
>        ptr = alloc_bootmem_core(pgdat->bdata, size, align, goal, 0);
> -#endif
>        if (ptr)
>                return ptr;
>
> @@ -1000,16 +849,7 @@ void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
>        if (WARN_ON_ONCE(slab_is_available()))
>                return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
>
> -#ifdef CONFIG_NO_BOOTMEM
> -       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> -                               goal, ARCH_LOW_ADDRESS_LIMIT);
> -       if (ptr)
> -               return ptr;
> -       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> -                               goal, ARCH_LOW_ADDRESS_LIMIT);
> -#else
>        ptr = ___alloc_bootmem_node(pgdat->bdata, size, align,
>                                goal, ARCH_LOW_ADDRESS_LIMIT);
> -#endif
>        return ptr;
>  }
> diff --git a/mm/nobootmem.c b/mm/nobootmem.c
> new file mode 100644
> index 000000000000..e93c3475011b
> --- /dev/null
> +++ b/mm/nobootmem.c
> @@ -0,0 +1,445 @@
> +/*
> + *  nobootmem - A boot-time physical memory allocator and configurator
> + *
> + *  Copyright (C) 1999 Ingo Molnar
> + *                1999 Kanoj Sarcar, SGI
> + *                2008 Johannes Weiner
> + *
> + *  Split out of bootmem.c by Namhyung Kim <namhyung@gmail.com>
> + *
> + * Access to this subsystem has to be serialized externally (which is true
> + * for the boot process anyway).
> + */
> +#include <linux/init.h>
> +#include <linux/pfn.h>
> +#include <linux/slab.h>
> +#include <linux/bootmem.h>
> +#include <linux/module.h>
> +#include <linux/kmemleak.h>
> +#include <linux/range.h>
> +#include <linux/memblock.h>
> +
> +#include <asm/bug.h>
> +#include <asm/io.h>
> +#include <asm/processor.h>
> +
> +#include "internal.h"
> +
> +unsigned long max_low_pfn;
> +unsigned long min_low_pfn;
> +unsigned long max_pfn;
> +
> +#ifdef CONFIG_CRASH_DUMP
> +/*
> + * If we have booted due to a crash, max_pfn will be a very low value. We need
> + * to know the amount of memory that the previous kernel used.
> + */
> +unsigned long saved_max_pfn;
> +#endif
> +
> +/**
> + * free_bootmem_late - free bootmem pages directly to page allocator
> + * @addr: starting address of the range
> + * @size: size of the range in bytes
> + *
> + * This is only useful when the bootmem allocator has already been torn
> + * down, but we are still initializing the system.  Pages are given directly
> + * to the page allocator, no bootmem metadata is updated because it is gone.
> + */
> +void __init free_bootmem_late(unsigned long addr, unsigned long size)
> +{
> +       unsigned long cursor, end;
> +
> +       kmemleak_free_part(__va(addr), size);
> +
> +       cursor = PFN_UP(addr);
> +       end = PFN_DOWN(addr + size);
> +
> +       for (; cursor < end; cursor++) {
> +               __free_pages_bootmem(pfn_to_page(cursor), 0);
> +               totalram_pages++;
> +       }
> +}
> +
> +static void __init __free_pages_memory(unsigned long start, unsigned long end)
> +{
> +       int i;
> +       unsigned long start_aligned, end_aligned;
> +       int order = ilog2(BITS_PER_LONG);
> +
> +       start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
> +       end_aligned = end & ~(BITS_PER_LONG - 1);
> +
> +       if (end_aligned <= start_aligned) {
> +               for (i = start; i < end; i++)
> +                       __free_pages_bootmem(pfn_to_page(i), 0);
> +
> +               return;
> +       }
> +
> +       for (i = start; i < start_aligned; i++)
> +               __free_pages_bootmem(pfn_to_page(i), 0);
> +
> +       for (i = start_aligned; i < end_aligned; i += BITS_PER_LONG)
> +               __free_pages_bootmem(pfn_to_page(i), order);
> +
> +       for (i = end_aligned; i < end; i++)
> +               __free_pages_bootmem(pfn_to_page(i), 0);
> +}
> +
> +unsigned long __init free_all_memory_core_early(int nodeid)
> +{
> +       int i;
> +       u64 start, end;
> +       unsigned long count = 0;
> +       struct range *range = NULL;
> +       int nr_range;
> +
> +       nr_range = get_free_all_memory_range(&range, nodeid);
> +
> +       for (i = 0; i < nr_range; i++) {
> +               start = range[i].start;
> +               end = range[i].end;
> +               count += end - start;
> +               __free_pages_memory(start, end);
> +       }
> +
> +       return count;
> +}
> +
> +/**
> + * free_all_bootmem_node - release a node's free pages to the buddy allocator
> + * @pgdat: node to be released
> + *
> + * Returns the number of pages actually released.
> + */
> +unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
> +{
> +       register_page_bootmem_info_node(pgdat);
> +
> +       /* free_all_memory_core_early(MAX_NUMNODES) will be called later */
> +       return 0;
> +}
> +
> +/**
> + * free_all_bootmem - release free pages to the buddy allocator
> + *
> + * Returns the number of pages actually released.
> + */
> +unsigned long __init free_all_bootmem(void)
> +{
> +       /*
> +        * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
> +        *  because in some case like Node0 doesnt have RAM installed
> +        *  low ram will be on Node1
> +        * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
> +        *  will be used instead of only Node0 related
> +        */
> +       return free_all_memory_core_early(MAX_NUMNODES);
> +}
> +
> +/**
> + * free_bootmem_node - mark a page range as usable
> + * @pgdat: node the range resides on
> + * @physaddr: starting address of the range
> + * @size: size of the range in bytes
> + *
> + * Partial pages will be considered reserved and left as they are.
> + *
> + * The range must reside completely on the specified node.
> + */
> +void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
> +                             unsigned long size)
> +{
> +       kmemleak_free_part(__va(physaddr), size);
> +       memblock_x86_free_range(physaddr, physaddr + size);
> +}
> +
> +/**
> + * free_bootmem - mark a page range as usable
> + * @addr: starting address of the range
> + * @size: size of the range in bytes
> + *
> + * Partial pages will be considered reserved and left as they are.
> + *
> + * The range must be contiguous but may span node boundaries.
> + */
> +void __init free_bootmem(unsigned long addr, unsigned long size)
> +{
> +       kmemleak_free_part(__va(addr), size);
> +       memblock_x86_free_range(addr, addr + size);
> +}
> +
> +/**
> + * reserve_bootmem_node - mark a page range as reserved
> + * @pgdat: node the range resides on
> + * @physaddr: starting address of the range
> + * @size: size of the range in bytes
> + * @flags: reservation flags (see linux/bootmem.h)
> + *
> + * Partial pages will be reserved.
> + *
> + * The range must reside completely on the specified node.
> + */
> +int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
> +                                unsigned long size, int flags)
> +{
> +       panic("no bootmem");
> +       return 0;
> +}
> +
> +/**
> + * reserve_bootmem - mark a page range as usable
> + * @addr: starting address of the range
> + * @size: size of the range in bytes
> + * @flags: reservation flags (see linux/bootmem.h)
> + *
> + * Partial pages will be reserved.
> + *
> + * The range must be contiguous but may span node boundaries.
> + */
> +int __init reserve_bootmem(unsigned long addr, unsigned long size,
> +                           int flags)
> +{
> +       panic("no bootmem");
> +       return 0;
> +}
> +
> +static void * __init ___alloc_bootmem_nopanic(unsigned long size,
> +                                       unsigned long align,
> +                                       unsigned long goal,
> +                                       unsigned long limit)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc(size, GFP_NOWAIT);
> +
> +restart:
> +
> +       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, goal, limit);
> +
> +       if (ptr)
> +               return ptr;
> +
> +       if (goal != 0) {
> +               goal = 0;
> +               goto restart;
> +       }
> +
> +       return NULL;
> +}
> +
> +/**
> + * __alloc_bootmem_nopanic - allocate boot memory without panicking
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may happen on any node in the system.
> + *
> + * Returns NULL on failure.
> + */
> +void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
> +                                       unsigned long goal)
> +{
> +       unsigned long limit = -1UL;
> +
> +       return ___alloc_bootmem_nopanic(size, align, goal, limit);
> +}
> +
> +static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
> +                                       unsigned long goal, unsigned long limit)
> +{
> +       void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
> +
> +       if (mem)
> +               return mem;
> +       /*
> +        * Whoops, we cannot satisfy the allocation request.
> +        */
> +       printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
> +       panic("Out of memory");
> +       return NULL;
> +}
> +
> +/**
> + * __alloc_bootmem - allocate boot memory
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may happen on any node in the system.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem(unsigned long size, unsigned long align,
> +                             unsigned long goal)
> +{
> +       unsigned long limit = -1UL;
> +
> +       return ___alloc_bootmem(size, align, goal, limit);
> +}
> +
> +/**
> + * __alloc_bootmem_node - allocate boot memory from a specific node
> + * @pgdat: node to allocate from
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may fall back to any node in the system if the specified node
> + * can not hold the requested memory.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
> +                                  unsigned long align, unsigned long goal)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> +                                        goal, -1ULL);
> +       if (ptr)
> +               return ptr;
> +
> +       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> +                                        goal, -1ULL);
> +
> +       return ptr;
> +}
> +
> +void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
> +                                  unsigned long align, unsigned long goal)
> +{
> +#ifdef MAX_DMA32_PFN
> +       unsigned long end_pfn;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       /* update goal according ...MAX_DMA32_PFN */
> +       end_pfn = pgdat->node_start_pfn + pgdat->node_spanned_pages;
> +
> +       if (end_pfn > MAX_DMA32_PFN + (128 >> (20 - PAGE_SHIFT)) &&
> +           (goal >> PAGE_SHIFT) < MAX_DMA32_PFN) {
> +               void *ptr;
> +               unsigned long new_goal;
> +
> +               new_goal = MAX_DMA32_PFN << PAGE_SHIFT;
> +               ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> +                                                new_goal, -1ULL);
> +               if (ptr)
> +                       return ptr;
> +       }
> +#endif
> +
> +       return __alloc_bootmem_node(pgdat, size, align, goal);
> +
> +}
> +
> +#ifdef CONFIG_SPARSEMEM
> +/**
> + * alloc_bootmem_section - allocate boot memory from a specific section
> + * @size: size of the request in bytes
> + * @section_nr: sparse map section to allocate from
> + *
> + * Return NULL on failure.
> + */
> +void * __init alloc_bootmem_section(unsigned long size,
> +                                   unsigned long section_nr)
> +{
> +       unsigned long pfn, goal, limit;
> +
> +       pfn = section_nr_to_pfn(section_nr);
> +       goal = pfn << PAGE_SHIFT;
> +       limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT;
> +
> +       return __alloc_memory_core_early(early_pfn_to_nid(pfn), size,
> +                                        SMP_CACHE_BYTES, goal, limit);
> +}
> +#endif
> +
> +void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
> +                                  unsigned long align, unsigned long goal)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       ptr =  __alloc_memory_core_early(pgdat->node_id, size, align,
> +                                                goal, -1ULL);
> +       if (ptr)
> +               return ptr;
> +
> +       return __alloc_bootmem_nopanic(size, align, goal);
> +}
> +
> +#ifndef ARCH_LOW_ADDRESS_LIMIT
> +#define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL
> +#endif
> +
> +/**
> + * __alloc_bootmem_low - allocate low boot memory
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may happen on any node in the system.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
> +                                 unsigned long goal)
> +{
> +       return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
> +}
> +
> +/**
> + * __alloc_bootmem_low_node - allocate low boot memory from a specific node
> + * @pgdat: node to allocate from
> + * @size: size of the request in bytes
> + * @align: alignment of the region
> + * @goal: preferred starting address of the region
> + *
> + * The goal is dropped if it can not be satisfied and the allocation will
> + * fall back to memory below @goal.
> + *
> + * Allocation may fall back to any node in the system if the specified node
> + * can not hold the requested memory.
> + *
> + * The function panics if the request can not be satisfied.
> + */
> +void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
> +                                      unsigned long align, unsigned long goal)
> +{
> +       void *ptr;
> +
> +       if (WARN_ON_ONCE(slab_is_available()))
> +               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
> +
> +       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
> +                               goal, ARCH_LOW_ADDRESS_LIMIT);
> +       if (ptr)
> +               return ptr;
> +
> +       ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
> +                               goal, ARCH_LOW_ADDRESS_LIMIT);
> +       return ptr;
> +}
> --
> 1.7.3.4.600.g982838b0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply

* Re: Why using configfs as the only interface is wrong for a storage target
From: Joel Becker @ 2011-02-07 18:45 UTC (permalink / raw)
  To: James Bottomley
  Cc: Bart Van Assche, Nicholas A. Bellinger, linux-scsi, Boaz Harrosh
In-Reply-To: <1297089709.3012.19.camel@mulgrave.site>

On Mon, Feb 07, 2011 at 08:41:49AM -0600, James Bottomley wrote:
> On Mon, 2011-02-07 at 03:53 -0800, Joel Becker wrote:
> > On Mon, Feb 07, 2011 at 12:41:18PM +0100, Bart Van Assche wrote:
> > > I'm still not convinced that using configfs in a storage target as the
> > > only interface between kernel space and user space is a good idea.

	Two points here.  First, a design principle of configfs is that
it cannot and should not be one-stop shop for all possible userspace
interaction.  If there are things that fit better in sysfs, there is no
reason the target code can't export them via sysfs.  So any contention
that we can't add other pieces of the puzzle in an attempt to shoehorn
everything into configfs is sub-optimal. 

> I think the overall philosophical point here, and it's a good one
> because I've heard it from several sources, is that it's not possible to
> separate configuration from status completely.  The classic example is
> where the kernel has to validate and adjust config information, but the

	Nor should you try.  You can certainly update the attributes of
objects created in configfs via the kernel, and you can certainly use
configfs with sysfs, ioctl, procfs, or netlink in the same subsystem.

Joel


-- 

Life's Little Instruction Book #226

	"When someone hugs you, let them be the first to let go."

			http://www.jlbec.org/
			jlbec@evilplan.org

^ permalink raw reply

* [PATCH] compiler, gcc: Unify macro definitions
From: Borislav Petkov @ 2011-02-07 18:46 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Borislav Petkov

From: Borislav Petkov <borislav.petkov@amd.com>

Unify identical gcc3.x and gcc4.x macros.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 include/linux/compiler-gcc.h  |    8 ++++++++
 include/linux/compiler-gcc3.h |    8 --------
 include/linux/compiler-gcc4.h |    8 --------
 3 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 16508bc..cb4c1eb 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -92,3 +92,11 @@
 #if !defined(__noclone)
 #define __noclone	/* not needed */
 #endif
+
+/*
+ * A trick to suppress uninitialized variable warning without generating any
+ * code
+ */
+#define uninitialized_var(x) x = x
+
+#define __always_inline		inline __attribute__((always_inline))
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
index b721129..37d4124 100644
--- a/include/linux/compiler-gcc3.h
+++ b/include/linux/compiler-gcc3.h
@@ -21,11 +21,3 @@
 #   error "GCOV profiling support for gcc versions below 3.4 not included"
 # endif /* __GNUC_MINOR__ */
 #endif /* CONFIG_GCOV_KERNEL */
-
-/*
- * A trick to suppress uninitialized variable warning without generating any
- * code
- */
-#define uninitialized_var(x) x = x
-
-#define __always_inline		inline __attribute__((always_inline))
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index fcfa5b9..64b7c00 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -12,13 +12,6 @@
 #define __used			__attribute__((__used__))
 #define __must_check 		__attribute__((warn_unused_result))
 #define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
-#define __always_inline		inline __attribute__((always_inline))
-
-/*
- * A trick to suppress uninitialized variable warning without generating any
- * code
- */
-#define uninitialized_var(x) x = x
 
 #if __GNUC_MINOR__ >= 3
 /* Mark functions as cold. gcc will assume any path leading to a call
@@ -53,7 +46,6 @@
 #define __noclone	__attribute__((__noclone__))
 
 #endif
-
 #endif
 
 #if __GNUC_MINOR__ > 0
-- 
1.7.4.rc2


^ permalink raw reply related

* Re: ext4: Fix data corruption with multi-block writepages support
From: Matt @ 2011-02-07 18:44 UTC (permalink / raw)
  To: Milan Broz; +Cc: Ted Ts'o, Linux Kernel, linux-ext4
In-Reply-To: <4D503A06.3010403@redhat.com>

On Mon, Feb 7, 2011 at 6:29 PM, Milan Broz <mbroz@redhat.com> wrote:
> On 02/07/2011 06:45 PM, Ted Ts'o wrote:
>> On Fri, Feb 04, 2011 at 10:40:47PM +0000, Matt wrote:
>>>
>>> So that means that the file-corruption which existed until 2.6.37-rc6
>>> and got triggered (for me) more easily via "dm crypt: scale to
>>> multiple CPUs"
>>> is fixed now ?
>>
>> Well, a patch exists for it that will be merged into 2.6.38.
>>
>>> That should give ext4 a nice speedup for >=2.6.38 :)
>>
>> I'm not going to make it be the default for 2.6.38, since it's fairly
>> late in the -rc features.  People who want it can explicitly enable it
>> using the mount option mblk_io_submit, though.  (And let me know your
>> success stories!  :-) I will be enabling it as the default in
>> 2.6.39-rc1.
>
> So it was ext4 only bug in ext4_end_bio(),
> dm-crypt per-cpu code was just trigger here, right?
>
> Milan
>

Hi Milan,

Well, that was at least the experience that I made

ext4: after Ted had disabled support for multiple page-io submission

I observed no data-corruption anymore (it had only appeared on the
system-partition, /home - where ext4 also is used or on my backup
partitions there was also no problem as far as I can tell)

XFS: no corruption observed

reiserfs: I can't say for sure since I'm only using it on my /boot partition :P

for other filesystems I can't say anything - I didn't use additional
ones at that time

Regards

Matt

^ permalink raw reply

* [PATCH/RFC] commit: fix memory-leak
From: Erik Faye-Lund @ 2011-02-07 18:40 UTC (permalink / raw)
  To: git; +Cc: msysgit, blees

The name, email and date strings are some times allocated on the
heap, but not free'd. Fix this by making sure they are allways
heap-allocated, so we can safely free the memory.

At the same time, this fixes a problem with strict-POSIX getenv
implementations. POSIX says "The return value from getenv() may
point to static data which may be overwritten by subsequent calls
to getenv()", so duplicating the strings is a potential bug.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---

This was found when investigating how to fix UTF-8 support in
getenv on Windows. I introduced the xgetenv-function (that returns
a pointer that can be passed to free) because I suspect we'll find
other similar code-paths.

 builtin/commit.c  |    9 ++++++---
 git-compat-util.h |    1 +
 wrapper.c         |    6 ++++++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 03cff5a..e5a649e 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -465,9 +465,9 @@ static void determine_author_info(struct strbuf *author_ident)
 {
 	char *name, *email, *date;
 
-	name = getenv("GIT_AUTHOR_NAME");
-	email = getenv("GIT_AUTHOR_EMAIL");
-	date = getenv("GIT_AUTHOR_DATE");
+	name = xgetenv("GIT_AUTHOR_NAME");
+	email = xgetenv("GIT_AUTHOR_EMAIL");
+	date = xgetenv("GIT_AUTHOR_DATE");
 
 	if (use_message && !renew_authorship) {
 		const char *a, *lb, *rb, *eol;
@@ -507,6 +507,9 @@ static void determine_author_info(struct strbuf *author_ident)
 		date = force_date;
 	strbuf_addstr(author_ident, fmt_ident(name, email, date,
 					      IDENT_ERROR_ON_NO_NAME));
+	free(name);
+	free(email);
+	free(date);
 }
 
 static int ends_rfc2822_footer(struct strbuf *sb)
diff --git a/git-compat-util.h b/git-compat-util.h
index d6d269f..12f111f 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -409,6 +409,7 @@ typedef void (*try_to_free_t)(size_t);
 extern try_to_free_t set_try_to_free_routine(try_to_free_t);
 
 extern char *xstrdup(const char *str);
+extern char *xgetenv(const char *name);
 extern void *xmalloc(size_t size);
 extern void *xmallocz(size_t size);
 extern void *xmemdupz(const void *data, size_t len);
diff --git a/wrapper.c b/wrapper.c
index 8d7dd31..e6173c4 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -30,6 +30,12 @@ char *xstrdup(const char *str)
 	return ret;
 }
 
+char *xgetenv(const char *name)
+{
+	char *tmp = getenv(name);
+	return tmp ? xstrdup(tmp) : NULL;
+}
+
 void *xmalloc(size_t size)
 {
 	void *ret = malloc(size);
-- 
1.7.4.msysgit.0

^ permalink raw reply related

* Re: [PATCH] exa: Flush (S)IFC to the frontbuffer immediately.
From: Maarten Maathuis @ 2011-02-07 18:38 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
In-Reply-To: <1297103867-5718-1-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

The reason for NV50+ is obvious, but i'm not sure NV04-NV4X should be
included for consistency or not.

On Mon, Feb 7, 2011 at 7:37 PM, Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> - NV50+: This avoids high latency while typing with core fonts for example.
>
> Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  src/nv04_exa.c |    4 ++++
>  src/nv50_exa.c |    4 ++++
>  src/nvc0_exa.c |    4 ++++
>  3 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/src/nv04_exa.c b/src/nv04_exa.c
> index 267c7b5..2603bd4 100644
> --- a/src/nv04_exa.c
> +++ b/src/nv04_exa.c
> @@ -340,6 +340,7 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
>                 PixmapPtr pDst, int x, int y, int w, int h, int cpp)
>  {
>        NVPtr pNv = NVPTR(pScrn);
> +       ScreenPtr pScreen = pDst->drawable.pScreen;
>        struct nouveau_channel *chan = pNv->chan;
>        struct nouveau_grobj *clip = pNv->NvClipRectangle;
>        struct nouveau_grobj *ifc = pNv->NvImageFromCpu;
> @@ -413,6 +414,9 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
>        }
>
>        chan->flush_notify = NULL;
> +
> +       if (pDst == pScreen->GetScreenPixmap(pScreen))
> +               FIRE_RING(chan);
>        return TRUE;
>  }
>
> diff --git a/src/nv50_exa.c b/src/nv50_exa.c
> index e8ff5aa..85baa68 100644
> --- a/src/nv50_exa.c
> +++ b/src/nv50_exa.c
> @@ -372,6 +372,7 @@ NV50EXAUploadSIFC(const char *src, int src_pitch,
>                  PixmapPtr pdpix, int x, int y, int w, int h, int cpp)
>  {
>        NV50EXA_LOCALS(pdpix);
> +       ScreenPtr pScreen = pdpix->drawable.pScreen;
>        int line_dwords = (w * cpp + 3) / 4;
>        uint32_t sifc_fmt;
>
> @@ -428,6 +429,9 @@ NV50EXAUploadSIFC(const char *src, int src_pitch,
>        }
>
>        chan->flush_notify = NULL;
> +
> +       if (pdpix == pScreen->GetScreenPixmap(pScreen))
> +               FIRE_RING(chan);
>        return TRUE;
>  }
>
> diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
> index 45647ce..85cb5d2 100644
> --- a/src/nvc0_exa.c
> +++ b/src/nvc0_exa.c
> @@ -550,6 +550,7 @@ NVC0EXAUploadSIFC(const char *src, int src_pitch,
>                  PixmapPtr pdpix, int x, int y, int w, int h, int cpp)
>  {
>        NVC0EXA_LOCALS(pdpix);
> +       ScreenPtr pScreen = pdpix->drawable.pScreen;
>        int line_dwords = (w * cpp + 3) / 4;
>        uint32_t sifc_fmt;
>
> @@ -608,6 +609,9 @@ NVC0EXAUploadSIFC(const char *src, int src_pitch,
>        }
>
>        chan->flush_notify = NULL;
> +
> +       if (pdpix == pScreen->GetScreenPixmap(pScreen))
> +               FIRE_RING(chan);
>        return TRUE;
>  }
>
> --
> 1.7.4.rc3
>
>



-- 
Far away from the primal instinct, the song seems to fade away, the
river get wider between your thoughts and the things we do and say.

^ permalink raw reply

* Re: microblaze: Convert irq chip to new functions
From: Michal Simek @ 2011-02-07 18:38 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: linux-kernel
In-Reply-To: <alpine.LFD.2.00.1102071935440.31804@localhost6.localdomain6>

Thomas Gleixner wrote:
> On Mon, 7 Feb 2011, Michal Simek wrote:
> 
>> Hi Thomas,
>>
>> I have tested them and there are several problems which I've fixed.
>> I have added that changes to your patch 2/3. I am sending them as v2.
>>
>> For all others patches:
>> Tested-by: Michal Simek <monstr@monstr.eu>
>>
>> They can go through your tree because you have all patches around irq.
> 
> They are not core code specific, so you can send them to linus in the
> .39 merge window.

Ok. I will take care about.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

^ permalink raw reply

* [PATCH] exa: Flush (S)IFC to the frontbuffer immediately.
From: Maarten Maathuis @ 2011-02-07 18:37 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

- NV50+: This avoids high latency while typing with core fonts for example.

Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 src/nv04_exa.c |    4 ++++
 src/nv50_exa.c |    4 ++++
 src/nvc0_exa.c |    4 ++++
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/src/nv04_exa.c b/src/nv04_exa.c
index 267c7b5..2603bd4 100644
--- a/src/nv04_exa.c
+++ b/src/nv04_exa.c
@@ -340,6 +340,7 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
 		 PixmapPtr pDst, int x, int y, int w, int h, int cpp)
 {
 	NVPtr pNv = NVPTR(pScrn);
+	ScreenPtr pScreen = pDst->drawable.pScreen;
 	struct nouveau_channel *chan = pNv->chan;
 	struct nouveau_grobj *clip = pNv->NvClipRectangle;
 	struct nouveau_grobj *ifc = pNv->NvImageFromCpu;
@@ -413,6 +414,9 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
 	}
 
 	chan->flush_notify = NULL;
+
+	if (pDst == pScreen->GetScreenPixmap(pScreen))
+		FIRE_RING(chan);
 	return TRUE;
 }
 
diff --git a/src/nv50_exa.c b/src/nv50_exa.c
index e8ff5aa..85baa68 100644
--- a/src/nv50_exa.c
+++ b/src/nv50_exa.c
@@ -372,6 +372,7 @@ NV50EXAUploadSIFC(const char *src, int src_pitch,
 		  PixmapPtr pdpix, int x, int y, int w, int h, int cpp)
 {
 	NV50EXA_LOCALS(pdpix);
+	ScreenPtr pScreen = pdpix->drawable.pScreen;
 	int line_dwords = (w * cpp + 3) / 4;
 	uint32_t sifc_fmt;
 
@@ -428,6 +429,9 @@ NV50EXAUploadSIFC(const char *src, int src_pitch,
 	}
 
 	chan->flush_notify = NULL;
+
+	if (pdpix == pScreen->GetScreenPixmap(pScreen))
+		FIRE_RING(chan);
 	return TRUE;
 }
 
diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
index 45647ce..85cb5d2 100644
--- a/src/nvc0_exa.c
+++ b/src/nvc0_exa.c
@@ -550,6 +550,7 @@ NVC0EXAUploadSIFC(const char *src, int src_pitch,
 		  PixmapPtr pdpix, int x, int y, int w, int h, int cpp)
 {
 	NVC0EXA_LOCALS(pdpix);
+	ScreenPtr pScreen = pdpix->drawable.pScreen;
 	int line_dwords = (w * cpp + 3) / 4;
 	uint32_t sifc_fmt;
 
@@ -608,6 +609,9 @@ NVC0EXAUploadSIFC(const char *src, int src_pitch,
 	}
 
 	chan->flush_notify = NULL;
+
+	if (pdpix == pScreen->GetScreenPixmap(pScreen))
+		FIRE_RING(chan);
 	return TRUE;
 }
 
-- 
1.7.4.rc3

^ permalink raw reply related

* Re: microblaze: Convert irq chip to new functions
From: Thomas Gleixner @ 2011-02-07 18:36 UTC (permalink / raw)
  To: Michal Simek; +Cc: linux-kernel
In-Reply-To: <1297102176-20768-1-git-send-email-monstr@monstr.eu>

On Mon, 7 Feb 2011, Michal Simek wrote:

> Hi Thomas,
> 
> I have tested them and there are several problems which I've fixed.
> I have added that changes to your patch 2/3. I am sending them as v2.
> 
> For all others patches:
> Tested-by: Michal Simek <monstr@monstr.eu>
> 
> They can go through your tree because you have all patches around irq.

They are not core code specific, so you can send them to linus in the
.39 merge window.

Thanks,

	tglx

^ permalink raw reply

* Re: [PATCH 0/2] cifs: don't perform SMB echoes on un-negotiated socket
From: Steve French @ 2011-02-07 18:36 UTC (permalink / raw)
  To: Jeff Layton; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA, jg-9fI4heB6ewM
In-Reply-To: <20110207132036.7af97f8f-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>

On Mon, Feb 7, 2011 at 12:20 PM, Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On Mon, 7 Feb 2011 11:42:05 -0600
> Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> On Mon, Feb 7, 2011 at 7:54 AM, Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>> > Commit 247ec9b4 makes the SMB echo workqueue job skip doing echoes
>> > unless the tcpStatus == CifsGood. Problem: tcpStatus == CifsGood is not
>> > a reliable indicator of whether the socket has had a NEGOTIATE done on
>> > it. This fixes that by adding a new tcpStatus of CifsNeedNegotiate that
>> > indicates this. It also cleans up cifs_reconnect_tcon a bit.
>> >
>> > This is not the only way to fix this issue. As Steve pointed out to me,
>> > we could also check to see whether there's a valid SMB session on the
>> > list as an indicator of whether a NEGOTIATE has been done. I think the
>> > approach I'm proposing clarifies the code better, but I'm willing to go
>> > with his approach if that's the general concensus.
>>
>> Jeff may be right that the code is clearer with this approach (I may try
>> to code the alternative to check) but ... we really shouldn't be sending
>> an SMBecho between negprot and sessionsetup anyway (so checking for
>> sessionsetup may make sense).
>>  If a negprot times out or
>> sessionsetup times out we don't need to be sending SMBecho
>> (on the other hand perhaps a really slow krb5 sessionsetup?)
>> Once a sessionsetup is sent, SMBechos make more sense.
>>
>
> Why shouldn't we send one between the negotiate and session setup? The
> MS-CIFS spec makes no mention that a session setup is required prior to
> doing an echo. You may be correct, but that's not really what the spec
> says.

I don't remember ever having seen one between negprot and sessionsetup
from other clients - but the broader point is that an SMBecho doesn't
serve any purpose in between negprot/sessionsetup (once at least one
session is setup, checking if the server stays up is more interesting)


-- 
Thanks,

Steve

^ permalink raw reply

* Re: chromium browser
From: Gary Thomas @ 2011-02-07 18:35 UTC (permalink / raw)
  To: Darren Hart; +Cc: poky
In-Reply-To: <4D50388A.4030707@linux.intel.com>

On 02/07/2011 11:23 AM, Darren Hart wrote:
> On 02/07/2011 04:51 AM, embedded.yogesh wrote:
>> On Monday 07 February 2011 05:45 PM, Gary Thomas wrote:
>>> On 02/06/2011 09:52 PM, yogesh lal wrote:
>>>> Hi,
>>>>
>>>> I am new to poky, so don't know it will make any sense or not, but
>>>> can we build chromium browser using Poky ?
>>>
>>> What's your target architecture? Last I checked, only x86 and ARM
>>> are supported.
>>>
>>> It can be done, but it's certainly not for the faint of heart :-)
>>>
>>
>> I am working on X86 platform. Can you give some initial start up where I
>> have to look ?
>
> Find and download the Chromium source, then have a look at the Poky Reference Guide for how to create an appropriate recipe, using recipes for projects with similar source layouts
> as examples.
>
> http://www.yoctoproject.org/docs/poky-ref-manual/poky-ref-manual.html

Probably a lot easier to start with the OpenEmbedded recipe
since it already works.  The biggest problem is that there
are a ton of dependencies, so you'll need to bring in those
recipes as well.

-- 
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------


^ permalink raw reply

* Re: "git add -u" broken in git 1.7.4?
From: SZEDER Gábor @ 2011-02-07 18:34 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Matthieu Moy, Sebastian Pipping, Michael J Gruber,
	Nguyen Thai Ngoc Duy, Git ML
In-Reply-To: <7vhbcguytf.fsf@alter.siamese.dyndns.org>

On Sun, Feb 06, 2011 at 10:46:20PM -0800, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
> 
> > Is "git add -p" broken, then? It takes pathspecs relative to the current
> > directory, but "git add -p" without arguments operates from the root,
> > not from the current subdirectory.
> 
> I would say so; "add -p" was an ill-executed afterthought.  The codepath
> was originally meant to be used from "-i" as the top-level interface that
> was a fully interactive way to prepare for the next commit, which is an
> operation that is inherently full-tree.
> 
> There are two schools of thought in previous threads discussing full-tree
> vs current-directory-relative.  I think each side has merits.
> 
> If we defaulted to the current directory (i.e. "git grep"), that would
> feel more natural as it is more consistent with how tools that are not git
> aware (e.g. "GNU grep" run in the same directory) behave.  A downside is
> when you are somewhere deep in a working tree, you have to know how deep
> you are and repeat "../" that many times, i.e. "git grep pattern ../../"
> 
> If we defaulted to the root-level (i.e. "git diff"), you do not have that
> downside (iow, "git diff" run from a deep directory is a full tree
> operation), and you can limit the scope to the current directory by a
> single dot, i.e. "git diff .".  A huge downside is that this may feel
> awkward for new people who do not yet breath git [*1*], as no other git
> aware tool would behave like this, limiting its scope to some directory
> that is higher above.
> 
> In the past, I have took the third position, saying that tools that
> semantically needs to be full-tree should be full-tree (i.e. ones that
> make or format commits), and others should be relative to the current
> directory (i.e. ones that are used to inspect your progress, such as
> grep), but that is not a very understandable guideline that people can
> easily follow.  If we have to choose between the two and make things
> consistent, my personal preference is to make everything relative to the
> current working directory.

_Everything_ relative to the current working directory?  I can't
imagine how would that work in practice.  Could you explain what would
the following commands do, for example, when they are relative to the
current working directory?

  $ cd t
  $ git checkout next
  $ git merge somebranch
  $ git reset HEAD^


Best,
Gábor

^ permalink raw reply

* Re: Scanning and channel types.
From: Daniel Halperin @ 2011-02-07 18:32 UTC (permalink / raw)
  To: Ben Greear; +Cc: Felix Fietkau, linux-wireless@vger.kernel.org
In-Reply-To: <4D5033DE.4070701@candelatech.com>

Start on 2.4 GHz AP with HT Only (not just HT40) set.  That is, AP
that doesn't allow 1 Mbps packets to be sent.  Scan, make sure 1 mbps
packets are sent.

Start on 5 GHZ AP with HT Only set.  Scan.  What rate are probes sent
at for 2.4 GHz?

Dan

On Mon, Feb 7, 2011 at 10:03 AM, Ben Greear <greearb@candelatech.com> wrote:
> On 02/06/2011 09:42 PM, Daniel Halperin wrote:
>>
>> Right. I think there is a function something like "send_rate_low" that
>> sends the lowest entry in the mac80211 enabled rates table for control
>> and mgmt packets.  If the NIC is associated to an HT Only AP then that
>> lowest entry should be HT20 MCS 1, I'd think.
>>
>> Also, does circumventing "set channel type" code work properly across
>> bands?  If you start on 5 GHz will it send 6 Mbps probes or 1 Mbps
>> probes?
>
> I did some tests with a sniffer set up:
>
> I have 8 STA vifs.
>
> 1)  AP is setup to run on channel 11, HT40-
>    Let all associate on channel 11, radio goes to HT40- mode.
>    Run Scan on operating channel:
>    Probe request is reported as 1Mbps data rate on ch 11.
>
> 2)  Scan on all channels:
>    Probe requests on 2.4Ghz channels are 1Mbps data rate.
>    Probe requests on 5Ghz channels (channel 40 in this case)
>    are reported as 6Mbps data rate.
>
> 3)  Kill AP, no VIFS are associated (radio goes to NO_HT)
>    Run scan on all channels.
>    Probe request on channel 40 is 6Mbps data rate.
>
>
> Please note that with my patches, the channel-type is still set to NO_HT
> if we are scanning off the operating channel.  Since test 1 appears to
> function properly, I think that verifies that we can safely send NO_HT
> requests while leaving the radio at HT40-.
>
> Please let me know if this answers your concerns.  If you can think of
> other combinations I should try, please let me know that as well.
>
> Thanks,
> Ben
>
> --
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc  http://www.candelatech.com
>
>

^ permalink raw reply

* Re: [PATCH, v3 2/2] cgroups: introduce timer slack subsystem
From: Kirill A. Shutemov @ 2011-02-07 18:32 UTC (permalink / raw)
  To: Jacob Pan
  Cc: Paul Menage, Li Zefan, containers, Arjan van de Ven, linux-kernel,
	Matt Helsley, Paul E. McKenney
In-Reply-To: <20110207092040.2e5c899b@putvin>

On Mon, Feb 07, 2011 at 09:20:40AM -0800, Jacob Pan wrote:
> On Mon, 7 Feb 2011 13:06:03 +0200
> "Kirill A. Shutemov" <kirill@shutemov.name> wrote:
> 
> > On Fri, Feb 04, 2011 at 09:27:55AM -0800, Jacob Pan wrote:
> > > On Fri, 4 Feb 2011 15:34:39 +0200
> > > "Kirill A. Shutemov" <kirill@shutemov.name> wrote:
> > > > What's mean "original timer slack" if you are free to move a task
> > > > between a lot of cgroups and process itself free to change it
> > > > anytime?
> > > > 
> > > 
> > > I need to manage tasks by a management software instead of letting
> > > the task change timer_slack by itself. The goal is to make
> > > management transparent and no modifications to the existing apps.
> > > Therefore, it is desirable to automatically enforce timer_slack
> > > when the apps are in the cgroup while automatically restore it when
> > > it is no longer under cgroup management.
> > 
> > Tasks are always under cgroup management. Root cgroup is still cgroup.
> > 
> > > So the "original timer slack" can be the default 50us or whatever
> > > value chosen by the task itself. But the app itself should not care
> > > or even be aware of which cgroup it is in.
> > > 
> > > So here are two optoins i can think of
> > > 1. add a new variable called cg_timer_slack_ns to struct
> > > task_struct{} cg_timer_slack_ns will be set by cgroup timer_slack
> > > subsystem, then we can retain the original per task value in
> > > timer_slack_ns. timer code will pick max(cg_timer_slack_ns,
> > > timer_slack_ns) if cg_timer_slack_ns is set.
> > > 
> > > 2. leave task_struct unchanged, add a current_timer_slack to the
> > > cgroup. timer_slack cgroup does not modify per task timer_slack_ns.
> > > similar to option #1, let timer code pick the timer_slack to use
> > > based on whether the task is in timer_slack cgroup.
> > > 
> > > Any thoughts?
> > 
> > I think it's over-engineering.
> > 
> We do have a real use case that cannot be solved by the current logic,
> I only want to find a solution.
> > What about configuration like this:
> > 
> >  root_cgroup
> >  |--timer_slack.min_slack_ns = 0
> >  |--timer_slack.max_slack_ns = ULONG_MAX
> >  |--50us
> >  |  |--timer_slack.min_slack_ns = 50000
> >  |  |--timer_slack.max_slack_ns = 50000
> >  |--500us
> >     |--timer_slack.min_slack_ns = 500000
> >     |--timer_slack_max_slack_ns = ULONG_MAX
> > 
> > If you want a task allow to drive its timer_slack, just leave it in
> > root_cgroup.
> > 
> > It you want to drive timer_slack of a task, move it between 50us and
> > 500um based on your policy.
> >  
> I surely agree with the dummy root configuration. But when the
> management software moves task among 50us or 500us cgroups, or back to
> dummy root, the timer slack cannot be automatically changed.
> 
> consider the following scenarios.
> 1. task_A has timer_slack = ts1 = 3us when it is running in the
> foreground by window manager
> 2. then it is moved to 50us cgroup because it is no longer in the
> foreground, so now ts1 = 50us. 
> 3. After a while, the system is running in the low power state, so
> task_A is moved to 500us cgroup, ts1 = 500us. Then the user switch the
> device into normal running state and put task_A in foreground again.
> 4. Management software then moves task_A from 500us cgroup to dummy
> root, but it will not be able to restore the 3us timer slack as needed
> by task_A. Task can surely drive its timer_slack but it breaks the
> cgroup-transparency desired by the management scheme.

Can you use 3us cgroup instead of moving to root cgroup? :)

I understand your use-case, but I can't provide sane interface to
implement this.

> The key is that tasks being managed are not aware of cgroup
> involvement. The management software is the one that moves tasks
> around, but we don't want the management software keeps track of very
> timer slacks value of every tasks. 
> 
> Thanks,
> Jacob

-- 
 Kirill A. Shutemov

^ permalink raw reply

* Re: [PATCH, v3 2/2] cgroups: introduce timer slack subsystem
From: Kirill A. Shutemov @ 2011-02-07 18:32 UTC (permalink / raw)
  To: Jacob Pan
  Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Paul Menage,
	Paul E. McKenney, Arjan van de Ven
In-Reply-To: <20110207092040.2e5c899b@putvin>

On Mon, Feb 07, 2011 at 09:20:40AM -0800, Jacob Pan wrote:
> On Mon, 7 Feb 2011 13:06:03 +0200
> "Kirill A. Shutemov" <kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org> wrote:
> 
> > On Fri, Feb 04, 2011 at 09:27:55AM -0800, Jacob Pan wrote:
> > > On Fri, 4 Feb 2011 15:34:39 +0200
> > > "Kirill A. Shutemov" <kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org> wrote:
> > > > What's mean "original timer slack" if you are free to move a task
> > > > between a lot of cgroups and process itself free to change it
> > > > anytime?
> > > > 
> > > 
> > > I need to manage tasks by a management software instead of letting
> > > the task change timer_slack by itself. The goal is to make
> > > management transparent and no modifications to the existing apps.
> > > Therefore, it is desirable to automatically enforce timer_slack
> > > when the apps are in the cgroup while automatically restore it when
> > > it is no longer under cgroup management.
> > 
> > Tasks are always under cgroup management. Root cgroup is still cgroup.
> > 
> > > So the "original timer slack" can be the default 50us or whatever
> > > value chosen by the task itself. But the app itself should not care
> > > or even be aware of which cgroup it is in.
> > > 
> > > So here are two optoins i can think of
> > > 1. add a new variable called cg_timer_slack_ns to struct
> > > task_struct{} cg_timer_slack_ns will be set by cgroup timer_slack
> > > subsystem, then we can retain the original per task value in
> > > timer_slack_ns. timer code will pick max(cg_timer_slack_ns,
> > > timer_slack_ns) if cg_timer_slack_ns is set.
> > > 
> > > 2. leave task_struct unchanged, add a current_timer_slack to the
> > > cgroup. timer_slack cgroup does not modify per task timer_slack_ns.
> > > similar to option #1, let timer code pick the timer_slack to use
> > > based on whether the task is in timer_slack cgroup.
> > > 
> > > Any thoughts?
> > 
> > I think it's over-engineering.
> > 
> We do have a real use case that cannot be solved by the current logic,
> I only want to find a solution.
> > What about configuration like this:
> > 
> >  root_cgroup
> >  |--timer_slack.min_slack_ns = 0
> >  |--timer_slack.max_slack_ns = ULONG_MAX
> >  |--50us
> >  |  |--timer_slack.min_slack_ns = 50000
> >  |  |--timer_slack.max_slack_ns = 50000
> >  |--500us
> >     |--timer_slack.min_slack_ns = 500000
> >     |--timer_slack_max_slack_ns = ULONG_MAX
> > 
> > If you want a task allow to drive its timer_slack, just leave it in
> > root_cgroup.
> > 
> > It you want to drive timer_slack of a task, move it between 50us and
> > 500um based on your policy.
> >  
> I surely agree with the dummy root configuration. But when the
> management software moves task among 50us or 500us cgroups, or back to
> dummy root, the timer slack cannot be automatically changed.
> 
> consider the following scenarios.
> 1. task_A has timer_slack = ts1 = 3us when it is running in the
> foreground by window manager
> 2. then it is moved to 50us cgroup because it is no longer in the
> foreground, so now ts1 = 50us. 
> 3. After a while, the system is running in the low power state, so
> task_A is moved to 500us cgroup, ts1 = 500us. Then the user switch the
> device into normal running state and put task_A in foreground again.
> 4. Management software then moves task_A from 500us cgroup to dummy
> root, but it will not be able to restore the 3us timer slack as needed
> by task_A. Task can surely drive its timer_slack but it breaks the
> cgroup-transparency desired by the management scheme.

Can you use 3us cgroup instead of moving to root cgroup? :)

I understand your use-case, but I can't provide sane interface to
implement this.

> The key is that tasks being managed are not aware of cgroup
> involvement. The management software is the one that moves tasks
> around, but we don't want the management software keeps track of very
> timer slacks value of every tasks. 
> 
> Thanks,
> Jacob

-- 
 Kirill A. Shutemov

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.