* [PATCH 1/1] net/usb: remove default in Kconfig for sierra_net driver
From: Elina Pasheva @ 2010-05-01 0:05 UTC (permalink / raw)
To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8,
rfiler-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
Subject: [PATCH 1/1] net/usb: remove default in Kconfig for sierra_net driver
From: Elina Pasheva <epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
The following patch removes the default from the Kconfig entry for sierra_net
driver as recommended.
All non-core drivers should default to "n".
This patch has been checked against net-2.6 tree.
Signed-off-by: Elina Pasheva <epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
Signed-off-by: Rory Filer <rfiler-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
---
drivers/net/usb/Kconfig | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 5d58abc..d7b7018 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -400,7 +400,6 @@ config USB_IPHETH
config USB_SIERRA_NET
tristate "USB-to-WWAN Driver for Sierra Wireless modems"
depends on USB_USBNET
- default y
help
Choose this option if you have a Sierra Wireless USB-to-WWAN device.
--
1.5.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [patch] ipv6: cleanup: remove unneeded null check
From: David Miller @ 2010-04-30 23:42 UTC (permalink / raw)
To: error27
Cc: netdev, kuznet, pekkas, jmorris, yoshfuji, kaber, eric.dumazet,
sri, herbert, emils.tantilov, kernel-janitors
In-Reply-To: <20100429143034.GI29093@bicker>
From: Dan Carpenter <error27@gmail.com>
Date: Thu, 29 Apr 2010 16:30:35 +0200
> We dereference "sk" unconditionally elsewhere in the function.
>
> This was left over from: b30bd282 "ip6_xmit: remove unnecessary NULL
> ptr check". According to that commit message, "the sk argument to
> ip6_xmit is never NULL nowadays since the skb->priority assigment
> expects a valid socket."
>
> Signed-off-by: Dan Carpenter <error27@gmail.com>
Applied, thanks Dan.
^ permalink raw reply
* Re: [PATCH] tcp: SO_TIMESTAMP implementation for TCP
From: David Miller @ 2010-04-30 23:41 UTC (permalink / raw)
To: therbert; +Cc: netdev
In-Reply-To: <i2i65634d661004300058s5ee1b177oee249d3d22baad62@mail.gmail.com>
From: Tom Herbert <therbert@google.com>
Date: Fri, 30 Apr 2010 00:58:32 -0700
>> All these new checks and branches for a feature of questionable value.
>
>> If you can modify you apps to grab this information you can also probe
>> for the information using external probing tools.
>>
> I don't see an nice way to do that, we're profiling a significant
> percentage of millions of connections over thousands of paths as part
> of standard operations while incurring negligible overhead. The app
> can can easily timestamp its operations, but without some mechanism
> for getting timestamps out of a TCP connection, the networking portion
> of servicing requests is pretty much a black box in that.
If other people have an opinion about this, now would be the time
to speak up. :-)
^ permalink raw reply
* Re: [PATCH] xfrm: potential uninitialized variable num_xfrms
From: David Miller @ 2010-04-30 23:40 UTC (permalink / raw)
To: xiaosuo; +Cc: hadi, timo.teras, herbert, adobriyan, netdev
In-Reply-To: <1272439222-2935-1-git-send-email-xiaosuo@gmail.com>
From: Changli Gao <xiaosuo@gmail.com>
Date: Wed, 28 Apr 2010 15:20:22 +0800
> potential uninitialized variable num_xfrms
>
> fix compiler warning: 'num_xfrms' may be used uninitialized in this function.
>
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
I decided to apply this after all, thanks!
^ permalink raw reply
* Re: [PATCH v6] net: batch skb dequeueing from softnet input_pkt_queue
From: David Miller @ 2010-04-30 23:38 UTC (permalink / raw)
To: ak
Cc: eric.dumazet, andi, hadi, xiaosuo, therbert, shemminger, netdev,
lenb, arjan
In-Reply-To: <20100429214144.GA10663@gargoyle.fritz.box>
From: Andi Kleen <ak@gargoyle.fritz.box>
Date: Thu, 29 Apr 2010 23:41:44 +0200
> Use io_schedule() in network stack to tell cpuidle governour to guarantee lower latencies
>
> XXX: probably too aggressive, some of these sleeps are not under high load.
>
> Based on a bug report from Eric Dumazet.
>
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
I like this, except that we probably don't want the delayacct_blkio_*() calls
these things do.
Probably the rest of what these things do should remain in the io_schedule*()
functions and the block layer can call it's own versions which add in the
delayacct_blkio_*() bits.
Or, if the delacct stuff is useful for socket I/O too, then it's interfaces
names should have the "blk" stripped from them :-)
^ permalink raw reply
* Re: [PATCH net-next-2.6] net: sock_def_readable() and friends RCU conversion
From: David Miller @ 2010-04-30 23:35 UTC (permalink / raw)
To: eric.dumazet; +Cc: hadi, xiaosuo, therbert, shemminger, netdev, eilong, bmb
In-Reply-To: <1272574909.2209.150.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 29 Apr 2010 23:01:49 +0200
> [PATCH net-next-2.6] net: sock_def_readable() and friends RCU conversion
So what's the difference between call_rcu() freeing this little waitqueue
struct and doing it for the entire socket?
We'll still be doing an RCU call every socket destroy, and now we also have
a new memory allocation/free per connection.
This has to show up in things like 'lat_connect' and friends, does it not?
^ permalink raw reply
* Re: [PATCH net-next-2.6] net: speedup sock_recv_ts_and_drops()
From: David Miller @ 2010-04-30 23:30 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1272518083.2201.119.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 29 Apr 2010 07:14:43 +0200
> sock_recv_ts_and_drops() is fat and slow (~ 4% of cpu time on some
> profiles)
>
> We can test all socket flags at once to make fast path fast again.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Nice, applied, thanks Eric.
I have a sneaking suspicion that there may be a few other places
like this. :-)
^ permalink raw reply
* Re: [PATCH/RFC Resubmission] cdc_ether: Identify MBM devices by GUID in MDLM descriptor
From: David Miller @ 2010-04-30 23:28 UTC (permalink / raw)
To: oneukum; +Cc: jonas.sjoquist, netdev
In-Reply-To: <201004281051.44212.oneukum@suse.de>
From: Oliver Neukum <oneukum@suse.de>
Date: Wed, 28 Apr 2010 10:51:44 +0200
> Am Mittwoch, 28. April 2010 02:09:59 schrieb David Miller:
>> From: Jonas Sjoquist <jonas.sjoquist@ericsson.com>
>> Date: Fri, 23 Apr 2010 13:07:45 +0200
>>
>> > From: Jonas Sjöquist <jonas.sjoquist@ericsson.com>
>> >
>> > This patch removes vid/pid for Ericsson MBM devices from the whitelist set of
>> > devices. The MBM devices are instead identified by GUID.
>> >
>> > In order for cdc_ether to handle these devices the GUID in the MDLM descriptor
>> > is tested. All MBM devices currently handled by cdc_ether as well as future
>> > CDC Ethernet MBM devices can be identified by the GUID.
>> >
>> > This is the same solution used in Carl Nordbeck's mbm driver,
>> > http://kerneltrap.org/mailarchive/linux-usb/2008/11/17/4141384/thread
>> >
>> > I post this as RFC to get feedback on however cdc_ether is the correct place to
>> > do the binding, or if it should be done in a separate driver, e.g. zaurus.
>> >
>> > Signed-off-by: Jonas Sjöquist <jonas.sjoquist@ericsson.com>
>>
>> Can someone knowledgable with the cdc_ether driver review this change?
>
> The patch looks good.
Applied to net-next-2.6, thanks everyone.
^ permalink raw reply
* Re: r8169 INFO: inconsistent lock state
From: David Miller @ 2010-04-30 23:20 UTC (permalink / raw)
To: romieu
Cc: eric.dumazet, sergey.senozhatsky, oleg, mingo, a.p.zijlstra,
netdev, linux-kernel
In-Reply-To: <20100430211556.GA4903@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 30 Apr 2010 23:15:56 +0200
> Eric Dumazet <eric.dumazet@gmail.com> :
> [...]
>> So we have following illegal chain (process context, not softirq)
>>
>> rtl8169_reset_task() -> tl8169_rx_interrupt() -> netif_receive_skb()
>>
>> And normally, commit 630b943c tried to change this chain to :
>>
>> rtl8169_reset_task() -> tl8169_rx_interrupt() -> netif_rx()
>>
>> I have no idea why it doesnt work.
>
> 630b943c appears to be in net-next.
>
> Oops ?
I just tossed this into net-2.6, thanks for noticing.
^ permalink raw reply
* Re: [PATCH] forcedeth: Stay in NAPI as long as there's work
From: David Miller @ 2010-04-30 23:17 UTC (permalink / raw)
To: therbert; +Cc: shemminger, joe, netdev, aabdulla
In-Reply-To: <h2m65634d661004281656j9f29fc2btdec0d6bcbee20f35@mail.gmail.com>
From: Tom Herbert <therbert@google.com>
Date: Wed, 28 Apr 2010 16:56:30 -0700
> On Wed, Apr 28, 2010 at 2:25 PM, David Miller <davem@davemloft.net> wrote:
>> From: Stephen Hemminger <shemminger@vyatta.com>
>> Date: Wed, 28 Apr 2010 11:25:28 -0700
>>
>>> The following does the same thing without the extra overhead
>>> of testing all the registers. It also handles the out of memory
>>> case.
>>>
>>> Compile tested only...
>>>
>>> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>>
>> Tom can you test this version?
>>
>
> Looks good. 406038 tps in my quick test which still is showing the
> benefits. Thanks for cleaning this up Stephen!
Thanks for testing, applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH]PM QOS refresh against next-20100430
From: Rafael J. Wysocki @ 2010-04-30 23:08 UTC (permalink / raw)
To: mgross
Cc: Kevin Hilman, aili, dwalker, tiwai, bruce.w.allan, davidb, mcgrof,
pavel, linux-pm, lkml, NetDev, Johannes Berg,
ACPI Devel Maling List, Len Brown, John W. Linville
In-Reply-To: <20100430230529.GA31391@linux.intel.com>
On Saturday 01 May 2010, mark gross wrote:
> On Sat, May 01, 2010 at 12:13:16AM +0200, Rafael J. Wysocki wrote:
> > On Friday 30 April 2010, mark gross wrote:
> > > The following is a refresh of the PM_QOS implementation, this patch
> > > updates some documentation input I got from Randy.
> > >
> > > This patch changes the string based list management to a handle base
> > > implementation to help with the hot path use of pm-qos, it also renames
> > > much of the API to use "request" as opposed to "requirement" that was
> > > used in the initial implementation. I did this because request more
> > > accurately represents what it actually does.
> > >
> > > Also, I added a string based ABI for users wanting to use a string
> > > interface. So if the user writes 0xDDDDDDDD formatted hex it will be
> > > accepted by the interface. (someone asked me for it and I don't think
> > > it hurts anything.)
> > >
> > > I really would like to get this refresh taken care of. Its been taking
> > > me too long to close this. please review or include it in next.
> > >
> > > Thanks!
> >
> > Well, I'd take it to suspend-2.6/linux-next, but first, it touches
> > subsystems whose maintainers were not in the Cc list, like the network
> > drivers, wireless and ACPI. The changes are trivial, so I hope they don't
> > mind.
> >
> > Second, my tree is based on the Linus' tree rather than linux-next and
> > the change in net/mac80211/scan.c doesn't seem to match that. Please tell me
> > what I'm supposed to do about that.
>
> You can waite for monday and I'll send a rebased version to linus' tree.
>
> I thought linux-next was where folks wanted me to put it.
>
> I'll email out a new one monday.
Great, thanks!
Rafael
^ permalink raw reply
* Re: [PATCH]PM QOS refresh against next-20100430
From: mark gross @ 2010-04-30 23:05 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Kevin Hilman, aili, dwalker, tiwai, bruce.w.allan, davidb, mcgrof,
pavel, linux-pm, lkml, NetDev, Johannes Berg,
ACPI Devel Maling List, Len Brown, John W. Linville
In-Reply-To: <201005010013.16262.rjw@sisk.pl>
On Sat, May 01, 2010 at 12:13:16AM +0200, Rafael J. Wysocki wrote:
> On Friday 30 April 2010, mark gross wrote:
> > The following is a refresh of the PM_QOS implementation, this patch
> > updates some documentation input I got from Randy.
> >
> > This patch changes the string based list management to a handle base
> > implementation to help with the hot path use of pm-qos, it also renames
> > much of the API to use "request" as opposed to "requirement" that was
> > used in the initial implementation. I did this because request more
> > accurately represents what it actually does.
> >
> > Also, I added a string based ABI for users wanting to use a string
> > interface. So if the user writes 0xDDDDDDDD formatted hex it will be
> > accepted by the interface. (someone asked me for it and I don't think
> > it hurts anything.)
> >
> > I really would like to get this refresh taken care of. Its been taking
> > me too long to close this. please review or include it in next.
> >
> > Thanks!
>
> Well, I'd take it to suspend-2.6/linux-next, but first, it touches
> subsystems whose maintainers were not in the Cc list, like the network
> drivers, wireless and ACPI. The changes are trivial, so I hope they don't
> mind.
>
> Second, my tree is based on the Linus' tree rather than linux-next and
> the change in net/mac80211/scan.c doesn't seem to match that. Please tell me
> what I'm supposed to do about that.
You can waite for monday and I'll send a rebased version to linus' tree.
I thought linux-next was where folks wanted me to put it.
I'll email out a new one monday.
Thanks,
--mgross
> Thanks,
> Rafael
>
>
> > Ooops! forgot the signed off by line!
> >
> > Signed-off-by: mark gross <mgross@linux.intel.com>
> >
> > From c45d8d86f89ac55fbb9a499fbc754e35258bf818 Mon Sep 17 00:00:00 2001
> > From: mgross <mark.gross@gmail.com>
> > Date: Sat, 13 Mar 2010 08:18:36 -0800
> > Subject: [PATCH 1/2] PM_QOS to use handle based list implementation and exported function name changes to be more descriptive of what is actually happening.
> >
> > ---
> > Documentation/power/pm_qos_interface.txt | 48 ++++---
> > drivers/acpi/processor_idle.c | 2 +-
> > drivers/cpuidle/governors/ladder.c | 2 +-
> > drivers/cpuidle/governors/menu.c | 2 +-
> > drivers/net/e1000e/netdev.c | 22 ++--
> > drivers/net/igbvf/netdev.c | 6 +-
> > drivers/net/wireless/ipw2x00/ipw2100.c | 11 +-
> > include/linux/netdevice.h | 4 +
> > include/linux/pm_qos_params.h | 14 +-
> > include/sound/pcm.h | 3 +-
> > kernel/pm_qos_params.c | 214 ++++++++++++++---------------
> > net/mac80211/mlme.c | 2 +-
> > net/mac80211/scan.c | 2 +-
> > sound/core/pcm.c | 3 -
> > sound/core/pcm_native.c | 14 +-
> > 15 files changed, 177 insertions(+), 172 deletions(-)
> >
> > diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt
> > index c40866e..bfed898 100644
> > --- a/Documentation/power/pm_qos_interface.txt
> > +++ b/Documentation/power/pm_qos_interface.txt
> > @@ -18,44 +18,46 @@ and pm_qos_params.h. This is done because having the available parameters
> > being runtime configurable or changeable from a driver was seen as too easy to
> > abuse.
> >
> > -For each parameter a list of performance requirements is maintained along with
> > +For each parameter a list of performance requests is maintained along with
> > an aggregated target value. The aggregated target value is updated with
> > -changes to the requirement list or elements of the list. Typically the
> > -aggregated target value is simply the max or min of the requirement values held
> > +changes to the request list or elements of the list. Typically the
> > +aggregated target value is simply the max or min of the request values held
> > in the parameter list elements.
> >
> > From kernel mode the use of this interface is simple:
> > -pm_qos_add_requirement(param_id, name, target_value):
> > -Will insert a named element in the list for that identified PM_QOS parameter
> > -with the target value. Upon change to this list the new target is recomputed
> > -and any registered notifiers are called only if the target value is now
> > -different.
> >
> > -pm_qos_update_requirement(param_id, name, new_target_value):
> > -Will search the list identified by the param_id for the named list element and
> > -then update its target value, calling the notification tree if the aggregated
> > -target is changed. with that name is already registered.
> > +handle = pm_qos_add_request(param_class, target_value):
> > +Will insert an element into the list for that identified PM_QOS class with the
> > +target value. Upon change to this list the new target is recomputed and any
> > +registered notifiers are called only if the target value is now different.
> > +Clients of pm_qos need to save the returned handle.
> >
> > -pm_qos_remove_requirement(param_id, name):
> > -Will search the identified list for the named element and remove it, after
> > -removal it will update the aggregate target and call the notification tree if
> > -the target was changed as a result of removing the named requirement.
> > +void pm_qos_update_request(handle, new_target_value):
> > +Will update the list element pointed to by the handle with the new target value
> > +and recompute the new aggregated target, calling the notification tree if the
> > +target is changed.
> > +
> > +void pm_qos_remove_request(handle):
> > +Will remove the element. After removal it will update the aggregate target and
> > +call the notification tree if the target was changed as a result of removing
> > +the request.
> >
> >
> > From user mode:
> > -Only processes can register a pm_qos requirement. To provide for automatic
> > -cleanup for process the interface requires the process to register its
> > -parameter requirements in the following way:
> > +Only processes can register a pm_qos request. To provide for automatic
> > +cleanup of a process, the interface requires the process to register its
> > +parameter requests in the following way:
> >
> > To register the default pm_qos target for the specific parameter, the process
> > must open one of /dev/[cpu_dma_latency, network_latency, network_throughput]
> >
> > As long as the device node is held open that process has a registered
> > -requirement on the parameter. The name of the requirement is "process_<PID>"
> > -derived from the current->pid from within the open system call.
> > +request on the parameter.
> >
> > -To change the requested target value the process needs to write a s32 value to
> > -the open device node. This translates to a pm_qos_update_requirement call.
> > +To change the requested target value the process needs to write an s32 value to
> > +the open device node. Alternatively the user mode program could write a hex
> > +string for the value using 10 char long format e.g. "0x12345678". This
> > +translates to a pm_qos_update_request call.
> >
> > To remove the user mode request for a target value simply close the device
> > node.
> > diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> > index 5939e7f..c3817e1 100644
> > --- a/drivers/acpi/processor_idle.c
> > +++ b/drivers/acpi/processor_idle.c
> > @@ -698,7 +698,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
> > "max_cstate: C%d\n"
> > "maximum allowed latency: %d usec\n",
> > pr->power.state ? pr->power.state - pr->power.states : 0,
> > - max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
> > + max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY));
> >
> > seq_puts(seq, "states:\n");
> >
> > diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
> > index 1c1ceb4..12c9890 100644
> > --- a/drivers/cpuidle/governors/ladder.c
> > +++ b/drivers/cpuidle/governors/ladder.c
> > @@ -67,7 +67,7 @@ static int ladder_select_state(struct cpuidle_device *dev)
> > struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
> > struct ladder_device_state *last_state;
> > int last_residency, last_idx = ldev->last_state_idx;
> > - int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
> > + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
> >
> > /* Special case when user has set very strict latency requirement */
> > if (unlikely(latency_req == 0)) {
> > diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
> > index 1aea715..61ca939 100644
> > --- a/drivers/cpuidle/governors/menu.c
> > +++ b/drivers/cpuidle/governors/menu.c
> > @@ -183,7 +183,7 @@ static u64 div_round64(u64 dividend, u32 divisor)
> > static int menu_select(struct cpuidle_device *dev)
> > {
> > struct menu_device *data = &__get_cpu_var(menu_devices);
> > - int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
> > + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
> > int i;
> > int multiplier;
> >
> > diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
> > index 904bd6b..7550879 100644
> > --- a/drivers/net/e1000e/netdev.c
> > +++ b/drivers/net/e1000e/netdev.c
> > @@ -2882,12 +2882,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
> > * excessive C-state transition latencies result in
> > * dropped transactions.
> > */
> > - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
> > - adapter->netdev->name, 55);
> > + pm_qos_update_request(
> > + adapter->netdev->pm_qos_req, 55);
> > } else {
> > - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
> > - adapter->netdev->name,
> > - PM_QOS_DEFAULT_VALUE);
> > + pm_qos_update_request(
> > + adapter->netdev->pm_qos_req,
> > + PM_QOS_DEFAULT_VALUE);
> > }
> > }
> >
> > @@ -3181,8 +3181,8 @@ int e1000e_up(struct e1000_adapter *adapter)
> >
> > /* DMA latency requirement to workaround early-receive/jumbo issue */
> > if (adapter->flags & FLAG_HAS_ERT)
> > - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
> > - adapter->netdev->name,
> > + adapter->netdev->pm_qos_req =
> > + pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
> > PM_QOS_DEFAULT_VALUE);
> >
> > /* hardware has been reset, we need to reload some things */
> > @@ -3244,9 +3244,11 @@ void e1000e_down(struct e1000_adapter *adapter)
> > e1000_clean_tx_ring(adapter);
> > e1000_clean_rx_ring(adapter);
> >
> > - if (adapter->flags & FLAG_HAS_ERT)
> > - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
> > - adapter->netdev->name);
> > + if (adapter->flags & FLAG_HAS_ERT) {
> > + pm_qos_remove_request(
> > + adapter->netdev->pm_qos_req);
> > + adapter->netdev->pm_qos_req = NULL;
> > + }
> >
> > /*
> > * TODO: for power management, we could drop the link and
> > diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
> > index 7012e3d..5e2b2a8 100644
> > --- a/drivers/net/igbvf/netdev.c
> > +++ b/drivers/net/igbvf/netdev.c
> > @@ -48,6 +48,7 @@
> > #define DRV_VERSION "1.0.0-k0"
> > char igbvf_driver_name[] = "igbvf";
> > const char igbvf_driver_version[] = DRV_VERSION;
> > +struct pm_qos_request_list *igbvf_driver_pm_qos_req;
> > static const char igbvf_driver_string[] =
> > "Intel(R) Virtual Function Network Driver";
> > static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
> > @@ -2901,7 +2902,7 @@ static int __init igbvf_init_module(void)
> > printk(KERN_INFO "%s\n", igbvf_copyright);
> >
> > ret = pci_register_driver(&igbvf_driver);
> > - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name,
> > + igbvf_driver_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
> > PM_QOS_DEFAULT_VALUE);
> >
> > return ret;
> > @@ -2917,7 +2918,8 @@ module_init(igbvf_init_module);
> > static void __exit igbvf_exit_module(void)
> > {
> > pci_unregister_driver(&igbvf_driver);
> > - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name);
> > + pm_qos_remove_request(igbvf_driver_pm_qos_req);
> > + igbvf_driver_pm_qos_req = NULL;
> > }
> > module_exit(igbvf_exit_module);
> >
> > diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
> > index 2088ac0..7040e3b 100644
> > --- a/drivers/net/wireless/ipw2x00/ipw2100.c
> > +++ b/drivers/net/wireless/ipw2x00/ipw2100.c
> > @@ -174,6 +174,8 @@ that only one external action is invoked at a time.
> > #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
> > #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
> >
> > +struct pm_qos_request_list *ipw2100_pm_qos_req;
> > +
> > /* Debugging stuff */
> > #ifdef CONFIG_IPW2100_DEBUG
> > #define IPW2100_RX_DEBUG /* Reception debugging */
> > @@ -1739,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
> > /* the ipw2100 hardware really doesn't want power management delays
> > * longer than 175usec
> > */
> > - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", 175);
> > + pm_qos_update_request(ipw2100_pm_qos_req, 175);
> >
> > /* If the interrupt is enabled, turn it off... */
> > spin_lock_irqsave(&priv->low_lock, flags);
> > @@ -1887,8 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
> > ipw2100_disable_interrupts(priv);
> > spin_unlock_irqrestore(&priv->low_lock, flags);
> >
> > - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
> > - PM_QOS_DEFAULT_VALUE);
> > + pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
> >
> > /* We have to signal any supplicant if we are disassociating */
> > if (associated)
> > @@ -6669,7 +6670,7 @@ static int __init ipw2100_init(void)
> > if (ret)
> > goto out;
> >
> > - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
> > + ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
> > PM_QOS_DEFAULT_VALUE);
> > #ifdef CONFIG_IPW2100_DEBUG
> > ipw2100_debug_level = debug;
> > @@ -6692,7 +6693,7 @@ static void __exit ipw2100_exit(void)
> > &driver_attr_debug_level);
> > #endif
> > pci_unregister_driver(&ipw2100_pci_driver);
> > - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100");
> > + pm_qos_remove_request(ipw2100_pm_qos_req);
> > }
> >
> > module_init(ipw2100_init);
> > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> > index 40d4c20..5dd6d8c 100644
> > --- a/include/linux/netdevice.h
> > +++ b/include/linux/netdevice.h
> > @@ -31,6 +31,7 @@
> > #include <linux/if_link.h>
> >
> > #ifdef __KERNEL__
> > +#include <linux/pm_qos_params.h>
> > #include <linux/timer.h>
> > #include <linux/delay.h>
> > #include <linux/mm.h>
> > @@ -778,6 +779,9 @@ struct net_device {
> > * the interface.
> > */
> > char name[IFNAMSIZ];
> > +
> > + struct pm_qos_request_list *pm_qos_req;
> > +
> > /* device name hash chain */
> > struct hlist_node name_hlist;
> > /* snmp alias */
> > diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
> > index d74f75e..8ba440e 100644
> > --- a/include/linux/pm_qos_params.h
> > +++ b/include/linux/pm_qos_params.h
> > @@ -14,12 +14,14 @@
> > #define PM_QOS_NUM_CLASSES 4
> > #define PM_QOS_DEFAULT_VALUE -1
> >
> > -int pm_qos_add_requirement(int qos, char *name, s32 value);
> > -int pm_qos_update_requirement(int qos, char *name, s32 new_value);
> > -void pm_qos_remove_requirement(int qos, char *name);
> > +struct pm_qos_request_list;
> >
> > -int pm_qos_requirement(int qos);
> > +struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value);
> > +void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
> > + s32 new_value);
> > +void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
> >
> > -int pm_qos_add_notifier(int qos, struct notifier_block *notifier);
> > -int pm_qos_remove_notifier(int qos, struct notifier_block *notifier);
> > +int pm_qos_request(int pm_qos_class);
> > +int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
> > +int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
> >
> > diff --git a/include/sound/pcm.h b/include/sound/pcm.h
> > index 8b611a5..dd76cde 100644
> > --- a/include/sound/pcm.h
> > +++ b/include/sound/pcm.h
> > @@ -29,6 +29,7 @@
> > #include <linux/poll.h>
> > #include <linux/mm.h>
> > #include <linux/bitops.h>
> > +#include <linux/pm_qos_params.h>
> >
> > #define snd_pcm_substream_chip(substream) ((substream)->private_data)
> > #define snd_pcm_chip(pcm) ((pcm)->private_data)
> > @@ -365,7 +366,7 @@ struct snd_pcm_substream {
> > int number;
> > char name[32]; /* substream name */
> > int stream; /* stream (direction) */
> > - char latency_id[20]; /* latency identifier */
> > + struct pm_qos_request_list *latency_pm_qos_req; /* pm_qos request */
> > size_t buffer_bytes_max; /* limit ring buffer size */
> > struct snd_dma_buffer dma_buffer;
> > unsigned int dma_buf_id;
> > diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
> > index 3db49b9..a1aea04 100644
> > --- a/kernel/pm_qos_params.c
> > +++ b/kernel/pm_qos_params.c
> > @@ -2,7 +2,7 @@
> > * This module exposes the interface to kernel space for specifying
> > * QoS dependencies. It provides infrastructure for registration of:
> > *
> > - * Dependents on a QoS value : register requirements
> > + * Dependents on a QoS value : register requests
> > * Watchers of QoS value : get notified when target QoS value changes
> > *
> > * This QoS design is best effort based. Dependents register their QoS needs.
> > @@ -14,19 +14,21 @@
> > * timeout: usec <-- currently not used.
> > * throughput: kbs (kilo byte / sec)
> > *
> > - * There are lists of pm_qos_objects each one wrapping requirements, notifiers
> > + * There are lists of pm_qos_objects each one wrapping requests, notifiers
> > *
> > - * User mode requirements on a QOS parameter register themselves to the
> > + * User mode requests on a QOS parameter register themselves to the
> > * subsystem by opening the device node /dev/... and writing there request to
> > * the node. As long as the process holds a file handle open to the node the
> > * client continues to be accounted for. Upon file release the usermode
> > - * requirement is removed and a new qos target is computed. This way when the
> > - * requirement that the application has is cleaned up when closes the file
> > + * request is removed and a new qos target is computed. This way when the
> > + * request that the application has is cleaned up when closes the file
> > * pointer or exits the pm_qos_object will get an opportunity to clean up.
> > *
> > * Mark Gross <mgross@linux.intel.com>
> > */
> >
> > +/*#define DEBUG*/
> > +
> > #include <linux/pm_qos_params.h>
> > #include <linux/sched.h>
> > #include <linux/spinlock.h>
> > @@ -42,25 +44,25 @@
> > #include <linux/uaccess.h>
> >
> > /*
> > - * locking rule: all changes to requirements or notifiers lists
> > + * locking rule: all changes to requests or notifiers lists
> > * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
> > * held, taken with _irqsave. One lock to rule them all
> > */
> > -struct requirement_list {
> > +struct pm_qos_request_list {
> > struct list_head list;
> > union {
> > s32 value;
> > s32 usec;
> > s32 kbps;
> > };
> > - char *name;
> > + int pm_qos_class;
> > };
> >
> > static s32 max_compare(s32 v1, s32 v2);
> > static s32 min_compare(s32 v1, s32 v2);
> >
> > struct pm_qos_object {
> > - struct requirement_list requirements;
> > + struct pm_qos_request_list requests;
> > struct blocking_notifier_head *notifiers;
> > struct miscdevice pm_qos_power_miscdev;
> > char *name;
> > @@ -72,7 +74,7 @@ struct pm_qos_object {
> > static struct pm_qos_object null_pm_qos;
> > static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
> > static struct pm_qos_object cpu_dma_pm_qos = {
> > - .requirements = {LIST_HEAD_INIT(cpu_dma_pm_qos.requirements.list)},
> > + .requests = {LIST_HEAD_INIT(cpu_dma_pm_qos.requests.list)},
> > .notifiers = &cpu_dma_lat_notifier,
> > .name = "cpu_dma_latency",
> > .default_value = 2000 * USEC_PER_SEC,
> > @@ -82,7 +84,7 @@ static struct pm_qos_object cpu_dma_pm_qos = {
> >
> > static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
> > static struct pm_qos_object network_lat_pm_qos = {
> > - .requirements = {LIST_HEAD_INIT(network_lat_pm_qos.requirements.list)},
> > + .requests = {LIST_HEAD_INIT(network_lat_pm_qos.requests.list)},
> > .notifiers = &network_lat_notifier,
> > .name = "network_latency",
> > .default_value = 2000 * USEC_PER_SEC,
> > @@ -93,8 +95,7 @@ static struct pm_qos_object network_lat_pm_qos = {
> >
> > static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
> > static struct pm_qos_object network_throughput_pm_qos = {
> > - .requirements =
> > - {LIST_HEAD_INIT(network_throughput_pm_qos.requirements.list)},
> > + .requests = {LIST_HEAD_INIT(network_throughput_pm_qos.requests.list)},
> > .notifiers = &network_throughput_notifier,
> > .name = "network_throughput",
> > .default_value = 0,
> > @@ -135,31 +136,34 @@ static s32 min_compare(s32 v1, s32 v2)
> > }
> >
> >
> > -static void update_target(int target)
> > +static void update_target(int pm_qos_class)
> > {
> > s32 extreme_value;
> > - struct requirement_list *node;
> > + struct pm_qos_request_list *node;
> > unsigned long flags;
> > int call_notifier = 0;
> >
> > spin_lock_irqsave(&pm_qos_lock, flags);
> > - extreme_value = pm_qos_array[target]->default_value;
> > + extreme_value = pm_qos_array[pm_qos_class]->default_value;
> > list_for_each_entry(node,
> > - &pm_qos_array[target]->requirements.list, list) {
> > - extreme_value = pm_qos_array[target]->comparitor(
> > + &pm_qos_array[pm_qos_class]->requests.list, list) {
> > + extreme_value = pm_qos_array[pm_qos_class]->comparitor(
> > extreme_value, node->value);
> > }
> > - if (atomic_read(&pm_qos_array[target]->target_value) != extreme_value) {
> > + if (atomic_read(&pm_qos_array[pm_qos_class]->target_value) !=
> > + extreme_value) {
> > call_notifier = 1;
> > - atomic_set(&pm_qos_array[target]->target_value, extreme_value);
> > - pr_debug(KERN_ERR "new target for qos %d is %d\n", target,
> > - atomic_read(&pm_qos_array[target]->target_value));
> > + atomic_set(&pm_qos_array[pm_qos_class]->target_value,
> > + extreme_value);
> > + pr_debug(KERN_ERR "new target for qos %d is %d\n", pm_qos_class,
> > + atomic_read(&pm_qos_array[pm_qos_class]->target_value));
> > }
> > spin_unlock_irqrestore(&pm_qos_lock, flags);
> >
> > if (call_notifier)
> > - blocking_notifier_call_chain(pm_qos_array[target]->notifiers,
> > - (unsigned long) extreme_value, NULL);
> > + blocking_notifier_call_chain(
> > + pm_qos_array[pm_qos_class]->notifiers,
> > + (unsigned long) extreme_value, NULL);
> > }
> >
> > static int register_pm_qos_misc(struct pm_qos_object *qos)
> > @@ -185,125 +189,110 @@ static int find_pm_qos_object_by_minor(int minor)
> > }
> >
> > /**
> > - * pm_qos_requirement - returns current system wide qos expectation
> > + * pm_qos_request - returns current system wide qos expectation
> > * @pm_qos_class: identification of which qos value is requested
> > *
> > * This function returns the current target value in an atomic manner.
> > */
> > -int pm_qos_requirement(int pm_qos_class)
> > +int pm_qos_request(int pm_qos_class)
> > {
> > return atomic_read(&pm_qos_array[pm_qos_class]->target_value);
> > }
> > -EXPORT_SYMBOL_GPL(pm_qos_requirement);
> > +EXPORT_SYMBOL_GPL(pm_qos_request);
> >
> > /**
> > - * pm_qos_add_requirement - inserts new qos request into the list
> > + * pm_qos_add_request - inserts new qos request into the list
> > * @pm_qos_class: identifies which list of qos request to us
> > - * @name: identifies the request
> > * @value: defines the qos request
> > *
> > * This function inserts a new entry in the pm_qos_class list of requested qos
> > * performance characteristics. It recomputes the aggregate QoS expectations
> > - * for the pm_qos_class of parameters.
> > + * for the pm_qos_class of parameters, and returns the pm_qos_request list
> > + * element as a handle for use in updating and removal. Call needs to save
> > + * this handle for later use.
> > */
> > -int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value)
> > +struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value)
> > {
> > - struct requirement_list *dep;
> > + struct pm_qos_request_list *dep;
> > unsigned long flags;
> >
> > - dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL);
> > + dep = kzalloc(sizeof(struct pm_qos_request_list), GFP_KERNEL);
> > if (dep) {
> > if (value == PM_QOS_DEFAULT_VALUE)
> > dep->value = pm_qos_array[pm_qos_class]->default_value;
> > else
> > dep->value = value;
> > - dep->name = kstrdup(name, GFP_KERNEL);
> > - if (!dep->name)
> > - goto cleanup;
> > + dep->pm_qos_class = pm_qos_class;
> >
> > spin_lock_irqsave(&pm_qos_lock, flags);
> > list_add(&dep->list,
> > - &pm_qos_array[pm_qos_class]->requirements.list);
> > + &pm_qos_array[pm_qos_class]->requests.list);
> > spin_unlock_irqrestore(&pm_qos_lock, flags);
> > update_target(pm_qos_class);
> > -
> > - return 0;
> > }
> >
> > -cleanup:
> > - kfree(dep);
> > - return -ENOMEM;
> > + return dep;
> > }
> > -EXPORT_SYMBOL_GPL(pm_qos_add_requirement);
> > +EXPORT_SYMBOL_GPL(pm_qos_add_request);
> >
> > /**
> > - * pm_qos_update_requirement - modifies an existing qos request
> > - * @pm_qos_class: identifies which list of qos request to us
> > - * @name: identifies the request
> > + * pm_qos_update_request - modifies an existing qos request
> > + * @pm_qos_req : handle to list element holding a pm_qos request to use
> > * @value: defines the qos request
> > *
> > - * Updates an existing qos requirement for the pm_qos_class of parameters along
> > + * Updates an existing qos request for the pm_qos_class of parameters along
> > * with updating the target pm_qos_class value.
> > *
> > - * If the named request isn't in the list then no change is made.
> > + * Attempts are made to make this code callable on hot code paths.
> > */
> > -int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value)
> > +void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
> > + s32 new_value)
> > {
> > unsigned long flags;
> > - struct requirement_list *node;
> > int pending_update = 0;
> > + s32 temp;
> >
> > spin_lock_irqsave(&pm_qos_lock, flags);
> > - list_for_each_entry(node,
> > - &pm_qos_array[pm_qos_class]->requirements.list, list) {
> > - if (strcmp(node->name, name) == 0) {
> > - if (new_value == PM_QOS_DEFAULT_VALUE)
> > - node->value =
> > - pm_qos_array[pm_qos_class]->default_value;
> > - else
> > - node->value = new_value;
> > - pending_update = 1;
> > - break;
> > - }
> > + if (new_value == PM_QOS_DEFAULT_VALUE)
> > + temp = pm_qos_array[pm_qos_req->pm_qos_class]->default_value;
> > + else
> > + temp = new_value;
> > +
> > + if (temp != pm_qos_req->value) {
> > + pending_update = 1;
> > + pm_qos_req->value = temp;
> > }
> > spin_unlock_irqrestore(&pm_qos_lock, flags);
> > if (pending_update)
> > - update_target(pm_qos_class);
> > -
> > - return 0;
> > + update_target(pm_qos_req->pm_qos_class);
> > }
> > -EXPORT_SYMBOL_GPL(pm_qos_update_requirement);
> > +EXPORT_SYMBOL_GPL(pm_qos_update_request);
> >
> > /**
> > - * pm_qos_remove_requirement - modifies an existing qos request
> > - * @pm_qos_class: identifies which list of qos request to us
> > - * @name: identifies the request
> > + * pm_qos_remove_request - modifies an existing qos request
> > + * @pm_qos_req: handle to request list element
> > *
> > - * Will remove named qos request from pm_qos_class list of parameters and
> > - * recompute the current target value for the pm_qos_class.
> > + * Will remove pm qos request from the list of requests and
> > + * recompute the current target value for the pm_qos_class. Call this
> > + * on slow code paths.
> > */
> > -void pm_qos_remove_requirement(int pm_qos_class, char *name)
> > +void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
> > {
> > unsigned long flags;
> > - struct requirement_list *node;
> > - int pending_update = 0;
> > + int qos_class;
> > +
> > + if (pm_qos_req == NULL)
> > + return;
> > + /* silent return to keep pcm code cleaner */
> >
> > + qos_class = pm_qos_req->pm_qos_class;
> > spin_lock_irqsave(&pm_qos_lock, flags);
> > - list_for_each_entry(node,
> > - &pm_qos_array[pm_qos_class]->requirements.list, list) {
> > - if (strcmp(node->name, name) == 0) {
> > - kfree(node->name);
> > - list_del(&node->list);
> > - kfree(node);
> > - pending_update = 1;
> > - break;
> > - }
> > - }
> > + list_del(&pm_qos_req->list);
> > + kfree(pm_qos_req);
> > spin_unlock_irqrestore(&pm_qos_lock, flags);
> > - if (pending_update)
> > - update_target(pm_qos_class);
> > + update_target(qos_class);
> > }
> > -EXPORT_SYMBOL_GPL(pm_qos_remove_requirement);
> > +EXPORT_SYMBOL_GPL(pm_qos_remove_request);
> >
> > /**
> > * pm_qos_add_notifier - sets notification entry for changes to target value
> > @@ -313,7 +302,7 @@ EXPORT_SYMBOL_GPL(pm_qos_remove_requirement);
> > * will register the notifier into a notification chain that gets called
> > * upon changes to the pm_qos_class target value.
> > */
> > - int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
> > +int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
> > {
> > int retval;
> >
> > @@ -343,21 +332,16 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
> > }
> > EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
> >
> > -#define PID_NAME_LEN 32
> > -
> > static int pm_qos_power_open(struct inode *inode, struct file *filp)
> > {
> > - int ret;
> > long pm_qos_class;
> > - char name[PID_NAME_LEN];
> >
> > pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
> > if (pm_qos_class >= 0) {
> > - filp->private_data = (void *)pm_qos_class;
> > - snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
> > - ret = pm_qos_add_requirement(pm_qos_class, name,
> > - PM_QOS_DEFAULT_VALUE);
> > - if (ret >= 0)
> > + filp->private_data = (void *) pm_qos_add_request(pm_qos_class,
> > + PM_QOS_DEFAULT_VALUE);
> > +
> > + if (filp->private_data)
> > return 0;
> > }
> > return -EPERM;
> > @@ -365,32 +349,40 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
> >
> > static int pm_qos_power_release(struct inode *inode, struct file *filp)
> > {
> > - int pm_qos_class;
> > - char name[PID_NAME_LEN];
> > + struct pm_qos_request_list *req;
> >
> > - pm_qos_class = (long)filp->private_data;
> > - snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
> > - pm_qos_remove_requirement(pm_qos_class, name);
> > + req = (struct pm_qos_request_list *)filp->private_data;
> > + pm_qos_remove_request(req);
> >
> > return 0;
> > }
> >
> > +
> > static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
> > size_t count, loff_t *f_pos)
> > {
> > s32 value;
> > - int pm_qos_class;
> > - char name[PID_NAME_LEN];
> > -
> > - pm_qos_class = (long)filp->private_data;
> > - if (count != sizeof(s32))
> > + int x;
> > + char ascii_value[11];
> > + struct pm_qos_request_list *pm_qos_req;
> > +
> > + if (count == sizeof(s32)) {
> > + if (copy_from_user(&value, buf, sizeof(s32)))
> > + return -EFAULT;
> > + } else if (count == 11) { /* len('0x12345678/0') */
> > + if (copy_from_user(ascii_value, buf, 11))
> > + return -EFAULT;
> > + x = sscanf(ascii_value, "%x", &value);
> > + if (x != 1)
> > + return -EINVAL;
> > + pr_debug(KERN_ERR "%s, %d, 0x%x\n", ascii_value, x, value);
> > + } else
> > return -EINVAL;
> > - if (copy_from_user(&value, buf, sizeof(s32)))
> > - return -EFAULT;
> > - snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
> > - pm_qos_update_requirement(pm_qos_class, name, value);
> >
> > - return sizeof(s32);
> > + pm_qos_req = (struct pm_qos_request_list *)filp->private_data;
> > + pm_qos_update_request(pm_qos_req, value);
> > +
> > + return count;
> > }
> >
> >
> > diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> > index 358226f..3deaac3 100644
> > --- a/net/mac80211/mlme.c
> > +++ b/net/mac80211/mlme.c
> > @@ -507,7 +507,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
> > s32 beaconint_us;
> >
> > if (latency < 0)
> > - latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
> > + latency = pm_qos_request(PM_QOS_NETWORK_LATENCY);
> >
> > beaconint_us = ieee80211_tu_to_usec(
> > found->vif.bss_conf.beacon_int);
> > diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> > index 8bc961f..be52bb8 100644
> > --- a/net/mac80211/scan.c
> > +++ b/net/mac80211/scan.c
> > @@ -510,7 +510,7 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
> > bad_latency = time_after(jiffies +
> > ieee80211_scan_get_channel_time(next_chan),
> > local->leave_oper_channel_time +
> > - usecs_to_jiffies(pm_qos_requirement(PM_QOS_NETWORK_LATENCY)));
> > + usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));
> >
> > listen_int_exceeded = time_after(jiffies +
> > ieee80211_scan_get_channel_time(next_chan),
> > diff --git a/sound/core/pcm.c b/sound/core/pcm.c
> > index 0d428d0..cbe815d 100644
> > --- a/sound/core/pcm.c
> > +++ b/sound/core/pcm.c
> > @@ -648,9 +648,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
> > substream->number = idx;
> > substream->stream = stream;
> > sprintf(substream->name, "subdevice #%i", idx);
> > - snprintf(substream->latency_id, sizeof(substream->latency_id),
> > - "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device,
> > - (stream ? 'c' : 'p'), idx);
> > substream->buffer_bytes_max = UINT_MAX;
> > if (prev == NULL)
> > pstr->substream = substream;
> > diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> > index c22ebb0..1bb0e23 100644
> > --- a/sound/core/pcm_native.c
> > +++ b/sound/core/pcm_native.c
> > @@ -481,11 +481,13 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
> > snd_pcm_timer_resolution_change(substream);
> > runtime->status->state = SNDRV_PCM_STATE_SETUP;
> >
> > - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
> > - substream->latency_id);
> > + if (substream->latency_pm_qos_req) {
> > + pm_qos_remove_request(substream->latency_pm_qos_req);
> > + substream->latency_pm_qos_req = NULL;
> > + }
> > if ((usecs = period_to_usecs(runtime)) >= 0)
> > - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
> > - substream->latency_id, usecs);
> > + substream->latency_pm_qos_req = pm_qos_add_request(
> > + PM_QOS_CPU_DMA_LATENCY, usecs);
> > return 0;
> > _error:
> > /* hardware might be unuseable from this time,
> > @@ -540,8 +542,8 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
> > if (substream->ops->hw_free)
> > result = substream->ops->hw_free(substream);
> > runtime->status->state = SNDRV_PCM_STATE_OPEN;
> > - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
> > - substream->latency_id);
> > + pm_qos_remove_request(substream->latency_pm_qos_req);
> > + substream->latency_pm_qos_req = NULL;
> > return result;
> > }
> >
> >
^ permalink raw reply
* Re: [Patch 1/3] sysctl: refactor integer handling proc code
From: Changli Gao @ 2010-04-30 22:49 UTC (permalink / raw)
To: Amerigo Wang
Cc: linux-kernel, Octavian Purdila, Eric Dumazet, penguin-kernel,
netdev, Neil Horman, ebiederm, David Miller, adobriyan
In-Reply-To: <20100430082925.5630.58453.sendpatchset@localhost.localdomain>
On Fri, Apr 30, 2010 at 4:25 PM, Amerigo Wang <amwang@redhat.com> wrote:
> (Based on Octavian's work, and I modified a lot.)
>
> As we are about to add another integer handling proc function a little
> bit of cleanup is in order: add a few helper functions to improve code
> readability and decrease code duplication.
>
> In the process a bug is also fixed: if the user specifies a number
> with more then 20 digits it will be interpreted as two integers
> (e.g. 10000...13 will be interpreted as 100.... and 13).
>
> Behavior for EFAULT handling was changed as well. Previous to this
> patch, when an EFAULT error occurred in the middle of a write
> operation, although some of the elements were set, that was not
> acknowledged to the user (by shorting the write and returning the
> number of bytes accepted). EFAULT is now treated just like any other
> errors by acknowledging the amount of bytes accepted.
>
> Signed-off-by: Octavian Purdila <opurdila@ixiacom.com>
> Signed-off-by: WANG Cong <amwang@redhat.com>
> Cc: Eric W. Biederman <ebiederm@xmission.com>
> ---
>
> Index: linux-2.6/kernel/sysctl.c
> ===================================================================
> --- linux-2.6.orig/kernel/sysctl.c
> +++ linux-2.6/kernel/sysctl.c
> @@ -2040,8 +2040,122 @@ int proc_dostring(struct ctl_table *tabl
> buffer, lenp, ppos);
> }
>
> +static size_t proc_skip_spaces(char **buf)
> +{
> + size_t ret;
> + char *tmp = skip_spaces(*buf);
> + ret = tmp - *buf;
> + *buf = tmp;
> + return ret;
> +}
> +
> +#define TMPBUFLEN 22
> +/**
> + * proc_get_long - reads an ASCII formated integer from a user buffer
> + *
> + * @buf - a kernel buffer
> + * @size - size of the kernel buffer
> + * @val - this is where the number will be stored
> + * @neg - set to %TRUE if number is negative
> + * @perm_tr - a vector which contains the allowed trailers
> + * @perm_tr_len - size of the perm_tr vector
> + * @tr - pointer to store the trailer character
> + *
> + * In case of success 0 is returned and buf and size are updated with
> + * the amount of bytes read. If tr is non NULL and a trailing
> + * character exist (size is non zero after returning from this
> + * function) tr is updated with the trailing character.
> + */
> +static int proc_get_long(char **buf, size_t *size,
> + unsigned long *val, bool *neg,
> + const char *perm_tr, unsigned perm_tr_len, char *tr)
> +{
> + int len;
> + char *p, tmp[TMPBUFLEN];
> +
> + if (!*size)
> + return -EINVAL;
> +
> + len = *size;
> + if (len > TMPBUFLEN-1)
> + len = TMPBUFLEN-1;
> +
> + memcpy(tmp, *buf, len);
> +
> + tmp[len] = 0;
> + p = tmp;
> + if (*p == '-' && *size > 1) {
> + *neg = 1;
As neg is bool*, you should use true and false instead of 1 and 0.
> + p++;
> + } else
> + *neg = 0;
> + if (!isdigit(*p))
> + return -EINVAL;
> +
> + *val = simple_strtoul(p, &p, 0);
>
> -static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
> + len = p - tmp;
> +
> + /* We don't know if the next char is whitespace thus we may accept
> + * invalid integers (e.g. 1234...a) or two integers instead of one
> + * (e.g. 123...1). So lets not allow such large numbers. */
> + if (len == TMPBUFLEN - 1)
> + return -EINVAL;
> +
> + if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len))
> + return -EINVAL;
> +
> + if (tr && (len < *size))
> + *tr = *p;
> +
> + *buf += len;
> + *size -= len;
> +
> + return 0;
> +}
> +
> +/**
> + * proc_put_long - coverts an integer to a decimal ASCII formated string
> + *
> + * @buf - the user buffer
> + * @size - the size of the user buffer
> + * @val - the integer to be converted
> + * @neg - sign of the number, %TRUE for negative
> + *
> + * In case of success 0 is returned and buf and size are updated with
> + * the amount of bytes read.
> + */
> +static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
> + bool neg)
> +{
> + int len;
> + char tmp[TMPBUFLEN], *p = tmp;
> +
> + sprintf(p, "%s%lu", neg ? "-" : "", val);
> + len = strlen(tmp);
> + if (len > *size)
> + len = *size;
> + if (copy_to_user(*buf, tmp, len))
> + return -EFAULT;
> + *size -= len;
> + *buf += len;
> + return 0;
> +}
> +#undef TMPBUFLEN
> +
> +static int proc_put_char(void __user **buf, size_t *size, char c)
> +{
> + if (*size) {
> + char __user **buffer = (char __user **)buf;
> + if (put_user(c, *buffer))
> + return -EFAULT;
> + (*size)--, (*buffer)++;
> + *buf = *buffer;
> + }
> + return 0;
> +}
> +
> +static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
> int *valp,
> int write, void *data)
> {
> @@ -2050,7 +2164,7 @@ static int do_proc_dointvec_conv(int *ne
> } else {
> int val = *valp;
> if (val < 0) {
> - *negp = -1;
> + *negp = 1;
> *lvalp = (unsigned long)-val;
> } else {
> *negp = 0;
> @@ -2060,23 +2174,21 @@ static int do_proc_dointvec_conv(int *ne
> return 0;
> }
>
> +static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
> +
> static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
> int write, void __user *buffer,
> size_t *lenp, loff_t *ppos,
> - int (*conv)(int *negp, unsigned long *lvalp, int *valp,
> + int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
> int write, void *data),
> void *data)
> {
> -#define TMPBUFLEN 21
> - int *i, vleft, first = 1, neg;
> - unsigned long lval;
> - size_t left, len;
> + int *i, vleft, first = 1, err = 0;
> + unsigned long page = 0;
> + size_t left;
> + char *kbuf;
>
> - char buf[TMPBUFLEN], *p;
> - char __user *s = buffer;
> -
> - if (!tbl_data || !table->maxlen || !*lenp ||
> - (*ppos && !write)) {
> + if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
> *lenp = 0;
> return 0;
> }
> @@ -2088,89 +2200,69 @@ static int __do_proc_dointvec(void *tbl_
> if (!conv)
> conv = do_proc_dointvec_conv;
>
> + if (write) {
> + if (left > PAGE_SIZE - 1)
> + left = PAGE_SIZE - 1;
> + page = __get_free_page(GFP_TEMPORARY);
> + kbuf = (char *) page;
> + if (!kbuf)
> + return -ENOMEM;
> + if (copy_from_user(kbuf, buffer, left)) {
> + err = -EFAULT;
> + goto free;
> + }
> + kbuf[left] = 0;
> + }
> +
> for (; left && vleft--; i++, first=0) {
> - if (write) {
> - while (left) {
> - char c;
> - if (get_user(c, s))
> - return -EFAULT;
> - if (!isspace(c))
> - break;
> - left--;
> - s++;
> - }
> - if (!left)
> - break;
> - neg = 0;
> - len = left;
> - if (len > sizeof(buf) - 1)
> - len = sizeof(buf) - 1;
> - if (copy_from_user(buf, s, len))
> - return -EFAULT;
> - buf[len] = 0;
> - p = buf;
> - if (*p == '-' && left > 1) {
> - neg = 1;
> - p++;
> - }
> - if (*p < '0' || *p > '9')
> - break;
> + unsigned long lval;
> + bool neg;
>
> - lval = simple_strtoul(p, &p, 0);
> + if (write) {
> + left -= proc_skip_spaces(&kbuf);
>
> - len = p-buf;
> - if ((len < left) && *p && !isspace(*p))
> + err = proc_get_long(&kbuf, &left, &lval, &neg,
> + proc_wspace_sep,
> + sizeof(proc_wspace_sep), NULL);
> + if (err)
> break;
> - s += len;
> - left -= len;
> -
> - if (conv(&neg, &lval, i, 1, data))
> + if (conv(&neg, &lval, i, 1, data)) {
> + err = -EINVAL;
> break;
> + }
> } else {
> - p = buf;
> + if (conv(&neg, &lval, i, 0, data)) {
> + err = -EINVAL;
> + break;
> + }
> if (!first)
> - *p++ = '\t';
> -
> - if (conv(&neg, &lval, i, 0, data))
> + err = proc_put_char(&buffer, &left, '\t');
> + if (err)
> + break;
> + err = proc_put_long(&buffer, &left, lval, neg);
> + if (err)
> break;
> -
> - sprintf(p, "%s%lu", neg ? "-" : "", lval);
> - len = strlen(buf);
> - if (len > left)
> - len = left;
> - if(copy_to_user(s, buf, len))
> - return -EFAULT;
> - left -= len;
> - s += len;
> }
> }
>
> - if (!write && !first && left) {
> - if(put_user('\n', s))
> - return -EFAULT;
> - left--, s++;
> - }
> + if (!write && !first && left && !err)
> + err = proc_put_char(&buffer, &left, '\n');
> + if (write && !err)
> + left -= proc_skip_spaces(&kbuf);
> +free:
> if (write) {
> - while (left) {
> - char c;
> - if (get_user(c, s++))
> - return -EFAULT;
> - if (!isspace(c))
> - break;
> - left--;
> - }
> + free_page(page);
> + if (first)
> + return err ? : -EINVAL;
> }
> - if (write && first)
> - return -EINVAL;
> *lenp -= left;
> *ppos += *lenp;
> - return 0;
> -#undef TMPBUFLEN
> + return err;
> }
>
> static int do_proc_dointvec(struct ctl_table *table, int write,
> void __user *buffer, size_t *lenp, loff_t *ppos,
> - int (*conv)(int *negp, unsigned long *lvalp, int *valp,
> + int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
> int write, void *data),
> void *data)
> {
> @@ -2238,8 +2330,8 @@ struct do_proc_dointvec_minmax_conv_para
> int *max;
> };
>
> -static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
> - int *valp,
> +static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp,
> + int *valp,
> int write, void *data)
> {
> struct do_proc_dointvec_minmax_conv_param *param = data;
> @@ -2252,7 +2344,7 @@ static int do_proc_dointvec_minmax_conv(
> } else {
> int val = *valp;
> if (val < 0) {
> - *negp = -1;
> + *negp = 1;
> *lvalp = (unsigned long)-val;
> } else {
> *negp = 0;
> @@ -2295,102 +2387,78 @@ static int __do_proc_doulongvec_minmax(v
> unsigned long convmul,
> unsigned long convdiv)
> {
> -#define TMPBUFLEN 21
> - unsigned long *i, *min, *max, val;
> - int vleft, first=1, neg;
> - size_t len, left;
> - char buf[TMPBUFLEN], *p;
> - char __user *s = buffer;
> -
> - if (!data || !table->maxlen || !*lenp ||
> - (*ppos && !write)) {
> + unsigned long *i, *min, *max;
> + int vleft, first = 1, err = 0;
> + unsigned long page = 0;
> + size_t left;
> + char *kbuf;
> +
> + if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {
> *lenp = 0;
> return 0;
> }
> -
> +
> i = (unsigned long *) data;
> min = (unsigned long *) table->extra1;
> max = (unsigned long *) table->extra2;
> vleft = table->maxlen / sizeof(unsigned long);
> left = *lenp;
> -
> +
> + if (write) {
> + if (left > PAGE_SIZE - 1)
> + left = PAGE_SIZE - 1;
> + page = __get_free_page(GFP_TEMPORARY);
> + kbuf = (char *) page;
> + if (!kbuf)
> + return -ENOMEM;
> + if (copy_from_user(kbuf, buffer, left)) {
> + err = -EFAULT;
> + goto free;
> + }
> + kbuf[left] = 0;
> + }
> +
> for (; left && vleft--; i++, min++, max++, first=0) {
> + unsigned long val;
> +
> if (write) {
> - while (left) {
> - char c;
> - if (get_user(c, s))
> - return -EFAULT;
> - if (!isspace(c))
> - break;
> - left--;
> - s++;
> - }
> - if (!left)
> - break;
> - neg = 0;
> - len = left;
> - if (len > TMPBUFLEN-1)
> - len = TMPBUFLEN-1;
> - if (copy_from_user(buf, s, len))
> - return -EFAULT;
> - buf[len] = 0;
> - p = buf;
> - if (*p == '-' && left > 1) {
> - neg = 1;
> - p++;
> - }
> - if (*p < '0' || *p > '9')
> - break;
> - val = simple_strtoul(p, &p, 0) * convmul / convdiv ;
> - len = p-buf;
> - if ((len < left) && *p && !isspace(*p))
> + bool neg;
> +
> + left -= proc_skip_spaces(&kbuf);
> +
> + err = proc_get_long(&kbuf, &left, &val, &neg,
> + proc_wspace_sep,
> + sizeof(proc_wspace_sep), NULL);
> + if (err)
> break;
> if (neg)
> - val = -val;
> - s += len;
> - left -= len;
> -
> - if(neg)
> continue;
> if ((min && val < *min) || (max && val > *max))
> continue;
> *i = val;
> } else {
> - p = buf;
> + val = convdiv * (*i) / convmul;
> if (!first)
> - *p++ = '\t';
> - sprintf(p, "%lu", convdiv * (*i) / convmul);
> - len = strlen(buf);
> - if (len > left)
> - len = left;
> - if(copy_to_user(s, buf, len))
> - return -EFAULT;
> - left -= len;
> - s += len;
> + err = proc_put_char(&buffer, &left, '\t');
> + err = proc_put_long(&buffer, &left, val, false);
> + if (err)
> + break;
> }
> }
>
> - if (!write && !first && left) {
> - if(put_user('\n', s))
> - return -EFAULT;
> - left--, s++;
> - }
> + if (!write && !first && left && !err)
> + err = proc_put_char(&buffer, &left, '\n');
> + if (write && !err)
> + left -= proc_skip_spaces(&kbuf);
> +free:
> if (write) {
> - while (left) {
> - char c;
> - if (get_user(c, s++))
> - return -EFAULT;
> - if (!isspace(c))
> - break;
> - left--;
> - }
> + free_page(page);
> + if (first)
> + return err ? : -EINVAL;
> }
> - if (write && first)
> - return -EINVAL;
> *lenp -= left;
> *ppos += *lenp;
> - return 0;
> -#undef TMPBUFLEN
> + return err;
> }
>
> static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
> @@ -2451,7 +2519,7 @@ int proc_doulongvec_ms_jiffies_minmax(st
> }
>
>
> -static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,
> +static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp,
> int *valp,
> int write, void *data)
> {
> @@ -2463,7 +2531,7 @@ static int do_proc_dointvec_jiffies_conv
> int val = *valp;
> unsigned long lval;
> if (val < 0) {
> - *negp = -1;
> + *negp = 1;
> lval = (unsigned long)-val;
> } else {
> *negp = 0;
> @@ -2474,7 +2542,7 @@ static int do_proc_dointvec_jiffies_conv
> return 0;
> }
>
> -static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,
> +static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long *lvalp,
> int *valp,
> int write, void *data)
> {
> @@ -2486,7 +2554,7 @@ static int do_proc_dointvec_userhz_jiffi
> int val = *valp;
> unsigned long lval;
> if (val < 0) {
> - *negp = -1;
> + *negp = 1;
> lval = (unsigned long)-val;
> } else {
> *negp = 0;
> @@ -2497,7 +2565,7 @@ static int do_proc_dointvec_userhz_jiffi
> return 0;
> }
>
> -static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
> +static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp,
> int *valp,
> int write, void *data)
> {
> @@ -2507,7 +2575,7 @@ static int do_proc_dointvec_ms_jiffies_c
> int val = *valp;
> unsigned long lval;
> if (val < 0) {
> - *negp = -1;
> + *negp = 1;
> lval = (unsigned long)-val;
> } else {
> *negp = 0;
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* Re: 2.6.34-rc5-git7 (plus all patches) -- another suspicious rcu_dereference_check() usage.
From: Paul E. McKenney @ 2010-04-30 22:48 UTC (permalink / raw)
To: Miles Lane
Cc: Vivek Goyal, Eric Paris, Lai Jiangshan, Ingo Molnar,
Peter Zijlstra, LKML, nauman, eric.dumazet, netdev, Jens Axboe,
Gui Jianfeng, Li Zefan, Johannes Berg
In-Reply-To: <h2ya44ae5cd1004261751waa5cb65ei3d139cbcfa2cc5cf@mail.gmail.com>
On Mon, Apr 26, 2010 at 08:51:06PM -0400, Miles Lane wrote:
> This one occurred during the wakeup from suspend to RAM.
>
> [ 984.724697] [ INFO: suspicious rcu_dereference_check() usage. ]
> [ 984.724700] ---------------------------------------------------
> [ 984.724703] include/linux/fdtable.h:88 invoked
> rcu_dereference_check() without protection!
> [ 984.724706]
> [ 984.724707] other info that might help us debug this:
> [ 984.724708]
> [ 984.724711]
> [ 984.724711] rcu_scheduler_active = 1, debug_locks = 1
> [ 984.724714] no locks held by dbus-daemon/4680.
> [ 984.724717]
> [ 984.724717] stack backtrace:
> [ 984.724721] Pid: 4680, comm: dbus-daemon Not tainted 2.6.34-rc5-git7 #33
> [ 984.724724] Call Trace:
> [ 984.724734] [<ffffffff81074556>] lockdep_rcu_dereference+0x9d/0xa6
> [ 984.724740] [<ffffffff810fc785>] fcheck_files+0xb1/0xc9
> [ 984.724745] [<ffffffff810fc7f5>] fget_light+0x35/0xab
> [ 984.724751] [<ffffffff81433e1b>] ? sock_poll_wait+0x13/0x18
> [ 984.724755] [<ffffffff81433e39>] ? unix_poll+0x19/0x95
> [ 984.724762] [<ffffffff8110aa95>] do_sys_poll+0x1ff/0x3e5
> [ 984.724766] [<ffffffff8110a19e>] ? __pollwait+0x0/0xc7
> [ 984.724771] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724776] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724780] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724784] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724788] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724793] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724797] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724802] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724806] [<ffffffff8110a265>] ? pollwake+0x0/0x4f
> [ 984.724812] [<ffffffff8110ae0f>] sys_poll+0x50/0xbb
> [ 984.724818] [<ffffffff81009d82>] system_call_fastpath+0x16/0x1b
And here, at long last, is the relevant patch.
Thanx, Paul
------------------------------------------------------------------------
commit dced7789910f0b1b4e9b94fe74d79f2c2f788399
Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Date: Fri Apr 30 15:24:24 2010 -0700
vfs: fix RCU-lockdep false positive due to /proc access
If a single-threaded process does a file-descriptor operation, and
some other process accesses that same file descriptor via /proc,
the current rcu_dereference_check_fdtable() can give a false-positive
RCU-lockdep splat due to the reference count being increased by the
/proc access after the reference-count check in fget_light() but before
the check in rcu_dereference_check_fdtable().
This commit prevents this false positive by checking for a single-threaded
process.
Located-by: Miles Lane <miles.lane@gmail.com>
Located-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 013dc52..e4a6d31 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -61,7 +61,8 @@ struct files_struct {
(rcu_dereference_check((fdtfd), \
rcu_read_lock_held() || \
lockdep_is_held(&(files)->file_lock) || \
- atomic_read(&(files)->count) == 1))
+ atomic_read(&(files)->count) == 1 || \
+ thread_group_empty(current)))
#define files_fdtable(files) \
(rcu_dereference_check_fdtable((files), (files)->fdt))
^ permalink raw reply related
* Re: [Patch 2/3] sysctl: add proc_do_large_bitmap
From: Changli Gao @ 2010-04-30 22:41 UTC (permalink / raw)
To: Amerigo Wang
Cc: linux-kernel, Octavian Purdila, Eric Dumazet, penguin-kernel,
netdev, Neil Horman, ebiederm, adobriyan, David Miller
In-Reply-To: <20100430082936.5630.67682.sendpatchset@localhost.localdomain>
On Fri, Apr 30, 2010 at 4:25 PM, Amerigo Wang <amwang@redhat.com> wrote:
> From: Octavian Purdila <opurdila@ixiacom.com>
>
> The new function can be used to read/write large bitmaps via /proc. A
> comma separated range format is used for compact output and input
> (e.g. 1,3-4,10-10).
>
> Writing into the file will first reset the bitmap then update it
> based on the given input.
>
> Signed-off-by: Octavian Purdila <opurdila@ixiacom.com>
> Signed-off-by: WANG Cong <amwang@redhat.com>
> Cc: Eric W. Biederman <ebiederm@xmission.com>
> ---
>
> Index: linux-2.6/include/linux/sysctl.h
> ===================================================================
> --- linux-2.6.orig/include/linux/sysctl.h
> +++ linux-2.6/include/linux/sysctl.h
> @@ -980,6 +980,8 @@ extern int proc_doulongvec_minmax(struct
> void __user *, size_t *, loff_t *);
> extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
> void __user *, size_t *, loff_t *);
> +extern int proc_do_large_bitmap(struct ctl_table *, int,
> + void __user *, size_t *, loff_t *);
>
> /*
> * Register a set of sysctl names by calling register_sysctl_table
> Index: linux-2.6/kernel/sysctl.c
> ===================================================================
> --- linux-2.6.orig/kernel/sysctl.c
> +++ linux-2.6/kernel/sysctl.c
> @@ -2049,6 +2049,16 @@ static size_t proc_skip_spaces(char **bu
> return ret;
> }
>
> +static void proc_skip_char(char **buf, size_t *size, const char v)
> +{
> + while (*size) {
> + if (**buf != v)
> + break;
> + (*size)--;
> + (*buf)++;
> + }
> +}
> +
> #define TMPBUFLEN 22
> /**
> * proc_get_long - reads an ASCII formated integer from a user buffer
> @@ -2675,6 +2685,153 @@ static int proc_do_cad_pid(struct ctl_ta
> return 0;
> }
>
> +/**
> + * proc_do_large_bitmap - read/write from/to a large bitmap
> + * @table: the sysctl table
> + * @write: %TRUE if this is a write to the sysctl file
> + * @buffer: the user buffer
> + * @lenp: the size of the user buffer
> + * @ppos: file position
> + *
> + * The bitmap is stored at table->data and the bitmap length (in bits)
> + * in table->maxlen.
> + *
> + * We use a range comma separated format (e.g. 1,3-4,10-10) so that
> + * large bitmaps may be represented in a compact manner. Writing into
> + * the file will clear the bitmap then update it with the given input.
> + *
> + * Returns 0 on success.
> + */
> +int proc_do_large_bitmap(struct ctl_table *table, int write,
> + void __user *buffer, size_t *lenp, loff_t *ppos)
> +{
> + int err = 0;
> + bool first = 1;
> + size_t left = *lenp;
> + unsigned long bitmap_len = table->maxlen;
> + unsigned long *bitmap = (unsigned long *) table->data;
> + unsigned long *tmp_bitmap = NULL;
> + char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c;
> +
> + if (!bitmap_len || !left || (*ppos && !write)) {
> + *lenp = 0;
> + return 0;
> + }
> +
> + if (write) {
> + unsigned long page = 0;
> + char *kbuf;
> +
> + if (left > PAGE_SIZE - 1)
> + left = PAGE_SIZE - 1;
> +
> + page = __get_free_page(GFP_TEMPORARY);
> + kbuf = (char *) page;
> + if (!kbuf)
> + return -ENOMEM;
> + if (copy_from_user(kbuf, buffer, left)) {
> + free_page(page);
> + return -EFAULT;
> + }
> + kbuf[left] = 0;
> +
> + tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long),
> + GFP_KERNEL);
> + if (!tmp_bitmap) {
> + free_page(page);
> + return -ENOMEM;
> + }
> + proc_skip_char(&kbuf, &left, '\n');
> + while (!err && left) {
> + unsigned long val_a, val_b;
> + bool neg;
> +
> + err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a,
> + sizeof(tr_a), &c);
> + if (err)
> + break;
> + if (val_a >= bitmap_len || neg) {
> + err = -EINVAL;
> + break;
> + }
> +
> + val_b = val_a;
> + if (left) {
> + kbuf++;
> + left--;
> + }
> +
> + if (c == '-') {
> + err = proc_get_long(&kbuf, &left, &val_b,
> + &neg, tr_b, sizeof(tr_b),
> + &c);
> + if (err)
> + break;
> + if (val_b >= bitmap_len || neg ||
> + val_a > val_b) {
> + err = -EINVAL;
> + break;
> + }
> + if (left) {
> + kbuf++;
> + left--;
> + }
> + }
> +
> + while (val_a <= val_b)
> + set_bit(val_a++, tmp_bitmap);
> +
> + first = 0;
> + proc_skip_char(&kbuf, &left, '\n');
> + }
> + free_page(page);
> + } else {
> + unsigned long bit_a, bit_b = 0;
> +
> + while (left) {
> + bit_a = find_next_bit(bitmap, bitmap_len, bit_b);
> + if (bit_a >= bitmap_len)
> + break;
> + bit_b = find_next_zero_bit(bitmap, bitmap_len,
> + bit_a + 1) - 1;
> +
> + if (!first) {
> + err = proc_put_char(&buffer, &left, ',');
> + if (err)
> + break;
> + }
> + err = proc_put_long(&buffer, &left, bit_a, false);
> + if (err)
> + break;
> + if (bit_a != bit_b) {
> + err = proc_put_char(&buffer, &left, '-');
> + if (err)
> + break;
> + err = proc_put_long(&buffer, &left, bit_b, false);
> + if (err)
> + break;
> + }
> +
> + first = 0; bit_b++;
> + }
> + if (!err)
> + err = proc_put_char(&buffer, &left, '\n');
> + }
> +
> + if (!err) {
add the following lines to let "echo 1-10 >>
/proc/..." work as normal.
if (write && *ppos)
bimap_or(bitmap, bitmap, tmp_bitmap,....)
else
> + if (write)
> + memcpy(bitmap, tmp_bitmap,
> + BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long));
> + kfree(tmp_bitmap);
> + *lenp -= left;
> + *ppos += *lenp;
> + return 0;
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* Re: OFT - reserving CPU's for networking
From: David Miller @ 2010-04-30 22:30 UTC (permalink / raw)
To: andi; +Cc: tglx, shemminger, eric.dumazet, netdev, peterz
In-Reply-To: <20100430210131.GA2833@gargoyle.fritz.box>
From: Andi Kleen <andi@firstfloor.org>
Date: Fri, 30 Apr 2010 23:01:31 +0200
> Besides it seems to me that dispatching is something the NIC should
> just do directly. "RPS only CPU" would be essentially just an
> interrupt mitigation/flow redirection scheme that a lot of NICs
> do anyways.
We've already established that the NIC can't do a complete job in all
important cases, that's why we've integrated the RPS/RFS patches in
the first place.
And we don't want it to, because the decision mechanisms for steering
that we using now are starting to get into the stateful territory and
that's verbotton for NIC offload as far as we're concerned.
^ permalink raw reply
* RE: ixgbe and mac-vlans problem
From: Tantilov, Emil S @ 2010-04-30 22:26 UTC (permalink / raw)
To: Ben Greear; +Cc: Arnd Bergmann, NetDev, Patrick McHardy
In-Reply-To: <4BDB57A6.1090400@candelatech.com>
Ben Greear wrote:
> On 04/30/2010 02:13 PM, Tantilov, Emil S wrote:
>> Ben Greear wrote:
>>> On 04/30/2010 11:00 AM, Arnd Bergmann wrote:
>>>> On Friday 30 April 2010 00:27:39 Ben Greear wrote:
>>>>> Basically, we create 50 mac-vlans, with sequential MAC addresses
>>>>> and sequential IP addresses, and set up ip rules properly.
>>>>>
>>>>> The issue is that only 10 or so of the mac-vlans receive other
>>>>> than broadcast packets. The ixgbe NIC doesn't show PROMISC mode.
>>>>
>>>> I just took a brief look at the driver and noticed that 82599
>>>> should be able to handle 128 entries before going into promisc
>>>> mode, while 82598 (the same driver) does 16.
>>>>
>>>> Maybe the logic for>16 entries is wrong, so you could try forcing
>>>> hw->mac.num_rar_entries to 16 for 82599 as well.
>>>
>>> I think I was actually on an 825998 system when I saw it yesterday,
>>> but I have seen similar issues on 82599, though I didn't take time
>>> to debug it fully, so it could have been something else.
>>>
>>> I will double-check the NIC chipset on the system that showed the
>>> problem yesterday.
>>
>> I ran a quick test in my setup with 82599 and was able to pass
>> traffic on all 50 mac-vlans without issues. This is on net-next.
>
> For an 82599 system, I can get 127 mac-vlans working out of 500
> created.
>
> That NIC also does not go PROMISC with lots (500) of mac-vlans.
>
> Once I put it in promisc mode manually, it works fine.
>
> So, I think whatever logic is supposed to put the NIC into promisc
> mode when it overflows it's lookup tables isn't working for ixgbe
> in 2.6.31.12.
Yeah, you're right. I was able to repro it.
We'll look into it.
Thanks,
Emil
^ permalink raw reply
* [patch] ipv6: cleanup: remove unneeded null check
From: Dan Carpenter @ 2010-04-29 14:30 UTC (permalink / raw)
To: netdev
Cc: Alexey Kuznetsov, Pekka Savola (ipv6), James Morris,
Hideaki YOSHIFUJI, Patrick McHardy, Eric Dumazet,
Sridhar Samudrala, Herbert Xu, Emil S Tantilov, David S. Miller,
kernel-janitors
We dereference "sk" unconditionally elsewhere in the function.
This was left over from: b30bd282 "ip6_xmit: remove unnecessary NULL
ptr check". According to that commit message, "the sk argument to
ip6_xmit is never NULL nowadays since the skb->priority assigment
expects a valid socket."
Signed-off-by: Dan Carpenter <error27@gmail.com>
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 75d5ef8..d26c6ae 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -218,8 +218,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
}
kfree_skb(skb);
skb = skb2;
- if (sk)
- skb_set_owner_w(skb, sk);
+ skb_set_owner_w(skb, sk);
}
if (opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
^ permalink raw reply related
* Re: ixgbe and mac-vlans problem
From: Ben Greear @ 2010-04-30 22:20 UTC (permalink / raw)
To: Tantilov, Emil S; +Cc: Arnd Bergmann, NetDev, Patrick McHardy
In-Reply-To: <EA929A9653AAE14F841771FB1DE5A1365FE55609F0@rrsmsx501.amr.corp.intel.com>
On 04/30/2010 02:13 PM, Tantilov, Emil S wrote:
> Ben Greear wrote:
>> On 04/30/2010 11:00 AM, Arnd Bergmann wrote:
>>> On Friday 30 April 2010 00:27:39 Ben Greear wrote:
>>>> Basically, we create 50 mac-vlans, with sequential MAC addresses
>>>> and sequential IP addresses, and set up ip rules properly.
>>>>
>>>> The issue is that only 10 or so of the mac-vlans receive other than
>>>> broadcast packets. The ixgbe NIC doesn't show PROMISC mode.
>>>
>>> I just took a brief look at the driver and noticed that 82599 should
>>> be able to handle 128 entries before going into promisc mode, while
>>> 82598 (the same driver) does 16.
>>>
>>> Maybe the logic for>16 entries is wrong, so you could try forcing
>>> hw->mac.num_rar_entries to 16 for 82599 as well.
>>
>> I think I was actually on an 825998 system when I saw it yesterday,
>> but I have seen similar issues on 82599, though I didn't take time
>> to debug it fully, so it could have been something else.
>>
>> I will double-check the NIC chipset on the system that showed the
>> problem yesterday.
>
> I ran a quick test in my setup with 82599 and was able to pass traffic
> on all 50 mac-vlans without issues. This is on net-next.
For an 82599 system, I can get 127 mac-vlans working out of 500 created.
That NIC also does not go PROMISC with lots (500) of mac-vlans.
Once I put it in promisc mode manually, it works fine.
So, I think whatever logic is supposed to put the NIC into promisc
mode when it overflows it's lookup tables isn't working for ixgbe
in 2.6.31.12.
Thanks,
Ben
>
> Thanks,
> Emil
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH]PM QOS refresh against next-20100430
From: Rafael J. Wysocki @ 2010-04-30 22:13 UTC (permalink / raw)
To: mgross
Cc: Kevin Hilman, aili, dwalker, tiwai, bruce.w.allan, davidb, mcgrof,
pavel, linux-pm, lkml, NetDev, Johannes Berg,
ACPI Devel Maling List, Len Brown, John W. Linville
In-Reply-To: <20100430212043.GA30315@linux.intel.com>
On Friday 30 April 2010, mark gross wrote:
> The following is a refresh of the PM_QOS implementation, this patch
> updates some documentation input I got from Randy.
>
> This patch changes the string based list management to a handle base
> implementation to help with the hot path use of pm-qos, it also renames
> much of the API to use "request" as opposed to "requirement" that was
> used in the initial implementation. I did this because request more
> accurately represents what it actually does.
>
> Also, I added a string based ABI for users wanting to use a string
> interface. So if the user writes 0xDDDDDDDD formatted hex it will be
> accepted by the interface. (someone asked me for it and I don't think
> it hurts anything.)
>
> I really would like to get this refresh taken care of. Its been taking
> me too long to close this. please review or include it in next.
>
> Thanks!
Well, I'd take it to suspend-2.6/linux-next, but first, it touches
subsystems whose maintainers were not in the Cc list, like the network
drivers, wireless and ACPI. The changes are trivial, so I hope they don't
mind.
Second, my tree is based on the Linus' tree rather than linux-next and
the change in net/mac80211/scan.c doesn't seem to match that. Please tell me
what I'm supposed to do about that.
Thanks,
Rafael
> Ooops! forgot the signed off by line!
>
> Signed-off-by: mark gross <mgross@linux.intel.com>
>
> From c45d8d86f89ac55fbb9a499fbc754e35258bf818 Mon Sep 17 00:00:00 2001
> From: mgross <mark.gross@gmail.com>
> Date: Sat, 13 Mar 2010 08:18:36 -0800
> Subject: [PATCH 1/2] PM_QOS to use handle based list implementation and exported function name changes to be more descriptive of what is actually happening.
>
> ---
> Documentation/power/pm_qos_interface.txt | 48 ++++---
> drivers/acpi/processor_idle.c | 2 +-
> drivers/cpuidle/governors/ladder.c | 2 +-
> drivers/cpuidle/governors/menu.c | 2 +-
> drivers/net/e1000e/netdev.c | 22 ++--
> drivers/net/igbvf/netdev.c | 6 +-
> drivers/net/wireless/ipw2x00/ipw2100.c | 11 +-
> include/linux/netdevice.h | 4 +
> include/linux/pm_qos_params.h | 14 +-
> include/sound/pcm.h | 3 +-
> kernel/pm_qos_params.c | 214 ++++++++++++++---------------
> net/mac80211/mlme.c | 2 +-
> net/mac80211/scan.c | 2 +-
> sound/core/pcm.c | 3 -
> sound/core/pcm_native.c | 14 +-
> 15 files changed, 177 insertions(+), 172 deletions(-)
>
> diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt
> index c40866e..bfed898 100644
> --- a/Documentation/power/pm_qos_interface.txt
> +++ b/Documentation/power/pm_qos_interface.txt
> @@ -18,44 +18,46 @@ and pm_qos_params.h. This is done because having the available parameters
> being runtime configurable or changeable from a driver was seen as too easy to
> abuse.
>
> -For each parameter a list of performance requirements is maintained along with
> +For each parameter a list of performance requests is maintained along with
> an aggregated target value. The aggregated target value is updated with
> -changes to the requirement list or elements of the list. Typically the
> -aggregated target value is simply the max or min of the requirement values held
> +changes to the request list or elements of the list. Typically the
> +aggregated target value is simply the max or min of the request values held
> in the parameter list elements.
>
> From kernel mode the use of this interface is simple:
> -pm_qos_add_requirement(param_id, name, target_value):
> -Will insert a named element in the list for that identified PM_QOS parameter
> -with the target value. Upon change to this list the new target is recomputed
> -and any registered notifiers are called only if the target value is now
> -different.
>
> -pm_qos_update_requirement(param_id, name, new_target_value):
> -Will search the list identified by the param_id for the named list element and
> -then update its target value, calling the notification tree if the aggregated
> -target is changed. with that name is already registered.
> +handle = pm_qos_add_request(param_class, target_value):
> +Will insert an element into the list for that identified PM_QOS class with the
> +target value. Upon change to this list the new target is recomputed and any
> +registered notifiers are called only if the target value is now different.
> +Clients of pm_qos need to save the returned handle.
>
> -pm_qos_remove_requirement(param_id, name):
> -Will search the identified list for the named element and remove it, after
> -removal it will update the aggregate target and call the notification tree if
> -the target was changed as a result of removing the named requirement.
> +void pm_qos_update_request(handle, new_target_value):
> +Will update the list element pointed to by the handle with the new target value
> +and recompute the new aggregated target, calling the notification tree if the
> +target is changed.
> +
> +void pm_qos_remove_request(handle):
> +Will remove the element. After removal it will update the aggregate target and
> +call the notification tree if the target was changed as a result of removing
> +the request.
>
>
> From user mode:
> -Only processes can register a pm_qos requirement. To provide for automatic
> -cleanup for process the interface requires the process to register its
> -parameter requirements in the following way:
> +Only processes can register a pm_qos request. To provide for automatic
> +cleanup of a process, the interface requires the process to register its
> +parameter requests in the following way:
>
> To register the default pm_qos target for the specific parameter, the process
> must open one of /dev/[cpu_dma_latency, network_latency, network_throughput]
>
> As long as the device node is held open that process has a registered
> -requirement on the parameter. The name of the requirement is "process_<PID>"
> -derived from the current->pid from within the open system call.
> +request on the parameter.
>
> -To change the requested target value the process needs to write a s32 value to
> -the open device node. This translates to a pm_qos_update_requirement call.
> +To change the requested target value the process needs to write an s32 value to
> +the open device node. Alternatively the user mode program could write a hex
> +string for the value using 10 char long format e.g. "0x12345678". This
> +translates to a pm_qos_update_request call.
>
> To remove the user mode request for a target value simply close the device
> node.
> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> index 5939e7f..c3817e1 100644
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -698,7 +698,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
> "max_cstate: C%d\n"
> "maximum allowed latency: %d usec\n",
> pr->power.state ? pr->power.state - pr->power.states : 0,
> - max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
> + max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY));
>
> seq_puts(seq, "states:\n");
>
> diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
> index 1c1ceb4..12c9890 100644
> --- a/drivers/cpuidle/governors/ladder.c
> +++ b/drivers/cpuidle/governors/ladder.c
> @@ -67,7 +67,7 @@ static int ladder_select_state(struct cpuidle_device *dev)
> struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
> struct ladder_device_state *last_state;
> int last_residency, last_idx = ldev->last_state_idx;
> - int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
> + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
>
> /* Special case when user has set very strict latency requirement */
> if (unlikely(latency_req == 0)) {
> diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
> index 1aea715..61ca939 100644
> --- a/drivers/cpuidle/governors/menu.c
> +++ b/drivers/cpuidle/governors/menu.c
> @@ -183,7 +183,7 @@ static u64 div_round64(u64 dividend, u32 divisor)
> static int menu_select(struct cpuidle_device *dev)
> {
> struct menu_device *data = &__get_cpu_var(menu_devices);
> - int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
> + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
> int i;
> int multiplier;
>
> diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
> index 904bd6b..7550879 100644
> --- a/drivers/net/e1000e/netdev.c
> +++ b/drivers/net/e1000e/netdev.c
> @@ -2882,12 +2882,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
> * excessive C-state transition latencies result in
> * dropped transactions.
> */
> - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
> - adapter->netdev->name, 55);
> + pm_qos_update_request(
> + adapter->netdev->pm_qos_req, 55);
> } else {
> - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
> - adapter->netdev->name,
> - PM_QOS_DEFAULT_VALUE);
> + pm_qos_update_request(
> + adapter->netdev->pm_qos_req,
> + PM_QOS_DEFAULT_VALUE);
> }
> }
>
> @@ -3181,8 +3181,8 @@ int e1000e_up(struct e1000_adapter *adapter)
>
> /* DMA latency requirement to workaround early-receive/jumbo issue */
> if (adapter->flags & FLAG_HAS_ERT)
> - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
> - adapter->netdev->name,
> + adapter->netdev->pm_qos_req =
> + pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
> PM_QOS_DEFAULT_VALUE);
>
> /* hardware has been reset, we need to reload some things */
> @@ -3244,9 +3244,11 @@ void e1000e_down(struct e1000_adapter *adapter)
> e1000_clean_tx_ring(adapter);
> e1000_clean_rx_ring(adapter);
>
> - if (adapter->flags & FLAG_HAS_ERT)
> - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
> - adapter->netdev->name);
> + if (adapter->flags & FLAG_HAS_ERT) {
> + pm_qos_remove_request(
> + adapter->netdev->pm_qos_req);
> + adapter->netdev->pm_qos_req = NULL;
> + }
>
> /*
> * TODO: for power management, we could drop the link and
> diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
> index 7012e3d..5e2b2a8 100644
> --- a/drivers/net/igbvf/netdev.c
> +++ b/drivers/net/igbvf/netdev.c
> @@ -48,6 +48,7 @@
> #define DRV_VERSION "1.0.0-k0"
> char igbvf_driver_name[] = "igbvf";
> const char igbvf_driver_version[] = DRV_VERSION;
> +struct pm_qos_request_list *igbvf_driver_pm_qos_req;
> static const char igbvf_driver_string[] =
> "Intel(R) Virtual Function Network Driver";
> static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
> @@ -2901,7 +2902,7 @@ static int __init igbvf_init_module(void)
> printk(KERN_INFO "%s\n", igbvf_copyright);
>
> ret = pci_register_driver(&igbvf_driver);
> - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name,
> + igbvf_driver_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
> PM_QOS_DEFAULT_VALUE);
>
> return ret;
> @@ -2917,7 +2918,8 @@ module_init(igbvf_init_module);
> static void __exit igbvf_exit_module(void)
> {
> pci_unregister_driver(&igbvf_driver);
> - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name);
> + pm_qos_remove_request(igbvf_driver_pm_qos_req);
> + igbvf_driver_pm_qos_req = NULL;
> }
> module_exit(igbvf_exit_module);
>
> diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
> index 2088ac0..7040e3b 100644
> --- a/drivers/net/wireless/ipw2x00/ipw2100.c
> +++ b/drivers/net/wireless/ipw2x00/ipw2100.c
> @@ -174,6 +174,8 @@ that only one external action is invoked at a time.
> #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
> #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
>
> +struct pm_qos_request_list *ipw2100_pm_qos_req;
> +
> /* Debugging stuff */
> #ifdef CONFIG_IPW2100_DEBUG
> #define IPW2100_RX_DEBUG /* Reception debugging */
> @@ -1739,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
> /* the ipw2100 hardware really doesn't want power management delays
> * longer than 175usec
> */
> - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", 175);
> + pm_qos_update_request(ipw2100_pm_qos_req, 175);
>
> /* If the interrupt is enabled, turn it off... */
> spin_lock_irqsave(&priv->low_lock, flags);
> @@ -1887,8 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
> ipw2100_disable_interrupts(priv);
> spin_unlock_irqrestore(&priv->low_lock, flags);
>
> - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
> - PM_QOS_DEFAULT_VALUE);
> + pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
>
> /* We have to signal any supplicant if we are disassociating */
> if (associated)
> @@ -6669,7 +6670,7 @@ static int __init ipw2100_init(void)
> if (ret)
> goto out;
>
> - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100",
> + ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
> PM_QOS_DEFAULT_VALUE);
> #ifdef CONFIG_IPW2100_DEBUG
> ipw2100_debug_level = debug;
> @@ -6692,7 +6693,7 @@ static void __exit ipw2100_exit(void)
> &driver_attr_debug_level);
> #endif
> pci_unregister_driver(&ipw2100_pci_driver);
> - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100");
> + pm_qos_remove_request(ipw2100_pm_qos_req);
> }
>
> module_init(ipw2100_init);
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 40d4c20..5dd6d8c 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -31,6 +31,7 @@
> #include <linux/if_link.h>
>
> #ifdef __KERNEL__
> +#include <linux/pm_qos_params.h>
> #include <linux/timer.h>
> #include <linux/delay.h>
> #include <linux/mm.h>
> @@ -778,6 +779,9 @@ struct net_device {
> * the interface.
> */
> char name[IFNAMSIZ];
> +
> + struct pm_qos_request_list *pm_qos_req;
> +
> /* device name hash chain */
> struct hlist_node name_hlist;
> /* snmp alias */
> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
> index d74f75e..8ba440e 100644
> --- a/include/linux/pm_qos_params.h
> +++ b/include/linux/pm_qos_params.h
> @@ -14,12 +14,14 @@
> #define PM_QOS_NUM_CLASSES 4
> #define PM_QOS_DEFAULT_VALUE -1
>
> -int pm_qos_add_requirement(int qos, char *name, s32 value);
> -int pm_qos_update_requirement(int qos, char *name, s32 new_value);
> -void pm_qos_remove_requirement(int qos, char *name);
> +struct pm_qos_request_list;
>
> -int pm_qos_requirement(int qos);
> +struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value);
> +void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
> + s32 new_value);
> +void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
>
> -int pm_qos_add_notifier(int qos, struct notifier_block *notifier);
> -int pm_qos_remove_notifier(int qos, struct notifier_block *notifier);
> +int pm_qos_request(int pm_qos_class);
> +int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
> +int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
>
> diff --git a/include/sound/pcm.h b/include/sound/pcm.h
> index 8b611a5..dd76cde 100644
> --- a/include/sound/pcm.h
> +++ b/include/sound/pcm.h
> @@ -29,6 +29,7 @@
> #include <linux/poll.h>
> #include <linux/mm.h>
> #include <linux/bitops.h>
> +#include <linux/pm_qos_params.h>
>
> #define snd_pcm_substream_chip(substream) ((substream)->private_data)
> #define snd_pcm_chip(pcm) ((pcm)->private_data)
> @@ -365,7 +366,7 @@ struct snd_pcm_substream {
> int number;
> char name[32]; /* substream name */
> int stream; /* stream (direction) */
> - char latency_id[20]; /* latency identifier */
> + struct pm_qos_request_list *latency_pm_qos_req; /* pm_qos request */
> size_t buffer_bytes_max; /* limit ring buffer size */
> struct snd_dma_buffer dma_buffer;
> unsigned int dma_buf_id;
> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
> index 3db49b9..a1aea04 100644
> --- a/kernel/pm_qos_params.c
> +++ b/kernel/pm_qos_params.c
> @@ -2,7 +2,7 @@
> * This module exposes the interface to kernel space for specifying
> * QoS dependencies. It provides infrastructure for registration of:
> *
> - * Dependents on a QoS value : register requirements
> + * Dependents on a QoS value : register requests
> * Watchers of QoS value : get notified when target QoS value changes
> *
> * This QoS design is best effort based. Dependents register their QoS needs.
> @@ -14,19 +14,21 @@
> * timeout: usec <-- currently not used.
> * throughput: kbs (kilo byte / sec)
> *
> - * There are lists of pm_qos_objects each one wrapping requirements, notifiers
> + * There are lists of pm_qos_objects each one wrapping requests, notifiers
> *
> - * User mode requirements on a QOS parameter register themselves to the
> + * User mode requests on a QOS parameter register themselves to the
> * subsystem by opening the device node /dev/... and writing there request to
> * the node. As long as the process holds a file handle open to the node the
> * client continues to be accounted for. Upon file release the usermode
> - * requirement is removed and a new qos target is computed. This way when the
> - * requirement that the application has is cleaned up when closes the file
> + * request is removed and a new qos target is computed. This way when the
> + * request that the application has is cleaned up when closes the file
> * pointer or exits the pm_qos_object will get an opportunity to clean up.
> *
> * Mark Gross <mgross@linux.intel.com>
> */
>
> +/*#define DEBUG*/
> +
> #include <linux/pm_qos_params.h>
> #include <linux/sched.h>
> #include <linux/spinlock.h>
> @@ -42,25 +44,25 @@
> #include <linux/uaccess.h>
>
> /*
> - * locking rule: all changes to requirements or notifiers lists
> + * locking rule: all changes to requests or notifiers lists
> * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
> * held, taken with _irqsave. One lock to rule them all
> */
> -struct requirement_list {
> +struct pm_qos_request_list {
> struct list_head list;
> union {
> s32 value;
> s32 usec;
> s32 kbps;
> };
> - char *name;
> + int pm_qos_class;
> };
>
> static s32 max_compare(s32 v1, s32 v2);
> static s32 min_compare(s32 v1, s32 v2);
>
> struct pm_qos_object {
> - struct requirement_list requirements;
> + struct pm_qos_request_list requests;
> struct blocking_notifier_head *notifiers;
> struct miscdevice pm_qos_power_miscdev;
> char *name;
> @@ -72,7 +74,7 @@ struct pm_qos_object {
> static struct pm_qos_object null_pm_qos;
> static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
> static struct pm_qos_object cpu_dma_pm_qos = {
> - .requirements = {LIST_HEAD_INIT(cpu_dma_pm_qos.requirements.list)},
> + .requests = {LIST_HEAD_INIT(cpu_dma_pm_qos.requests.list)},
> .notifiers = &cpu_dma_lat_notifier,
> .name = "cpu_dma_latency",
> .default_value = 2000 * USEC_PER_SEC,
> @@ -82,7 +84,7 @@ static struct pm_qos_object cpu_dma_pm_qos = {
>
> static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
> static struct pm_qos_object network_lat_pm_qos = {
> - .requirements = {LIST_HEAD_INIT(network_lat_pm_qos.requirements.list)},
> + .requests = {LIST_HEAD_INIT(network_lat_pm_qos.requests.list)},
> .notifiers = &network_lat_notifier,
> .name = "network_latency",
> .default_value = 2000 * USEC_PER_SEC,
> @@ -93,8 +95,7 @@ static struct pm_qos_object network_lat_pm_qos = {
>
> static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
> static struct pm_qos_object network_throughput_pm_qos = {
> - .requirements =
> - {LIST_HEAD_INIT(network_throughput_pm_qos.requirements.list)},
> + .requests = {LIST_HEAD_INIT(network_throughput_pm_qos.requests.list)},
> .notifiers = &network_throughput_notifier,
> .name = "network_throughput",
> .default_value = 0,
> @@ -135,31 +136,34 @@ static s32 min_compare(s32 v1, s32 v2)
> }
>
>
> -static void update_target(int target)
> +static void update_target(int pm_qos_class)
> {
> s32 extreme_value;
> - struct requirement_list *node;
> + struct pm_qos_request_list *node;
> unsigned long flags;
> int call_notifier = 0;
>
> spin_lock_irqsave(&pm_qos_lock, flags);
> - extreme_value = pm_qos_array[target]->default_value;
> + extreme_value = pm_qos_array[pm_qos_class]->default_value;
> list_for_each_entry(node,
> - &pm_qos_array[target]->requirements.list, list) {
> - extreme_value = pm_qos_array[target]->comparitor(
> + &pm_qos_array[pm_qos_class]->requests.list, list) {
> + extreme_value = pm_qos_array[pm_qos_class]->comparitor(
> extreme_value, node->value);
> }
> - if (atomic_read(&pm_qos_array[target]->target_value) != extreme_value) {
> + if (atomic_read(&pm_qos_array[pm_qos_class]->target_value) !=
> + extreme_value) {
> call_notifier = 1;
> - atomic_set(&pm_qos_array[target]->target_value, extreme_value);
> - pr_debug(KERN_ERR "new target for qos %d is %d\n", target,
> - atomic_read(&pm_qos_array[target]->target_value));
> + atomic_set(&pm_qos_array[pm_qos_class]->target_value,
> + extreme_value);
> + pr_debug(KERN_ERR "new target for qos %d is %d\n", pm_qos_class,
> + atomic_read(&pm_qos_array[pm_qos_class]->target_value));
> }
> spin_unlock_irqrestore(&pm_qos_lock, flags);
>
> if (call_notifier)
> - blocking_notifier_call_chain(pm_qos_array[target]->notifiers,
> - (unsigned long) extreme_value, NULL);
> + blocking_notifier_call_chain(
> + pm_qos_array[pm_qos_class]->notifiers,
> + (unsigned long) extreme_value, NULL);
> }
>
> static int register_pm_qos_misc(struct pm_qos_object *qos)
> @@ -185,125 +189,110 @@ static int find_pm_qos_object_by_minor(int minor)
> }
>
> /**
> - * pm_qos_requirement - returns current system wide qos expectation
> + * pm_qos_request - returns current system wide qos expectation
> * @pm_qos_class: identification of which qos value is requested
> *
> * This function returns the current target value in an atomic manner.
> */
> -int pm_qos_requirement(int pm_qos_class)
> +int pm_qos_request(int pm_qos_class)
> {
> return atomic_read(&pm_qos_array[pm_qos_class]->target_value);
> }
> -EXPORT_SYMBOL_GPL(pm_qos_requirement);
> +EXPORT_SYMBOL_GPL(pm_qos_request);
>
> /**
> - * pm_qos_add_requirement - inserts new qos request into the list
> + * pm_qos_add_request - inserts new qos request into the list
> * @pm_qos_class: identifies which list of qos request to us
> - * @name: identifies the request
> * @value: defines the qos request
> *
> * This function inserts a new entry in the pm_qos_class list of requested qos
> * performance characteristics. It recomputes the aggregate QoS expectations
> - * for the pm_qos_class of parameters.
> + * for the pm_qos_class of parameters, and returns the pm_qos_request list
> + * element as a handle for use in updating and removal. Call needs to save
> + * this handle for later use.
> */
> -int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value)
> +struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value)
> {
> - struct requirement_list *dep;
> + struct pm_qos_request_list *dep;
> unsigned long flags;
>
> - dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL);
> + dep = kzalloc(sizeof(struct pm_qos_request_list), GFP_KERNEL);
> if (dep) {
> if (value == PM_QOS_DEFAULT_VALUE)
> dep->value = pm_qos_array[pm_qos_class]->default_value;
> else
> dep->value = value;
> - dep->name = kstrdup(name, GFP_KERNEL);
> - if (!dep->name)
> - goto cleanup;
> + dep->pm_qos_class = pm_qos_class;
>
> spin_lock_irqsave(&pm_qos_lock, flags);
> list_add(&dep->list,
> - &pm_qos_array[pm_qos_class]->requirements.list);
> + &pm_qos_array[pm_qos_class]->requests.list);
> spin_unlock_irqrestore(&pm_qos_lock, flags);
> update_target(pm_qos_class);
> -
> - return 0;
> }
>
> -cleanup:
> - kfree(dep);
> - return -ENOMEM;
> + return dep;
> }
> -EXPORT_SYMBOL_GPL(pm_qos_add_requirement);
> +EXPORT_SYMBOL_GPL(pm_qos_add_request);
>
> /**
> - * pm_qos_update_requirement - modifies an existing qos request
> - * @pm_qos_class: identifies which list of qos request to us
> - * @name: identifies the request
> + * pm_qos_update_request - modifies an existing qos request
> + * @pm_qos_req : handle to list element holding a pm_qos request to use
> * @value: defines the qos request
> *
> - * Updates an existing qos requirement for the pm_qos_class of parameters along
> + * Updates an existing qos request for the pm_qos_class of parameters along
> * with updating the target pm_qos_class value.
> *
> - * If the named request isn't in the list then no change is made.
> + * Attempts are made to make this code callable on hot code paths.
> */
> -int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value)
> +void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
> + s32 new_value)
> {
> unsigned long flags;
> - struct requirement_list *node;
> int pending_update = 0;
> + s32 temp;
>
> spin_lock_irqsave(&pm_qos_lock, flags);
> - list_for_each_entry(node,
> - &pm_qos_array[pm_qos_class]->requirements.list, list) {
> - if (strcmp(node->name, name) == 0) {
> - if (new_value == PM_QOS_DEFAULT_VALUE)
> - node->value =
> - pm_qos_array[pm_qos_class]->default_value;
> - else
> - node->value = new_value;
> - pending_update = 1;
> - break;
> - }
> + if (new_value == PM_QOS_DEFAULT_VALUE)
> + temp = pm_qos_array[pm_qos_req->pm_qos_class]->default_value;
> + else
> + temp = new_value;
> +
> + if (temp != pm_qos_req->value) {
> + pending_update = 1;
> + pm_qos_req->value = temp;
> }
> spin_unlock_irqrestore(&pm_qos_lock, flags);
> if (pending_update)
> - update_target(pm_qos_class);
> -
> - return 0;
> + update_target(pm_qos_req->pm_qos_class);
> }
> -EXPORT_SYMBOL_GPL(pm_qos_update_requirement);
> +EXPORT_SYMBOL_GPL(pm_qos_update_request);
>
> /**
> - * pm_qos_remove_requirement - modifies an existing qos request
> - * @pm_qos_class: identifies which list of qos request to us
> - * @name: identifies the request
> + * pm_qos_remove_request - modifies an existing qos request
> + * @pm_qos_req: handle to request list element
> *
> - * Will remove named qos request from pm_qos_class list of parameters and
> - * recompute the current target value for the pm_qos_class.
> + * Will remove pm qos request from the list of requests and
> + * recompute the current target value for the pm_qos_class. Call this
> + * on slow code paths.
> */
> -void pm_qos_remove_requirement(int pm_qos_class, char *name)
> +void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
> {
> unsigned long flags;
> - struct requirement_list *node;
> - int pending_update = 0;
> + int qos_class;
> +
> + if (pm_qos_req == NULL)
> + return;
> + /* silent return to keep pcm code cleaner */
>
> + qos_class = pm_qos_req->pm_qos_class;
> spin_lock_irqsave(&pm_qos_lock, flags);
> - list_for_each_entry(node,
> - &pm_qos_array[pm_qos_class]->requirements.list, list) {
> - if (strcmp(node->name, name) == 0) {
> - kfree(node->name);
> - list_del(&node->list);
> - kfree(node);
> - pending_update = 1;
> - break;
> - }
> - }
> + list_del(&pm_qos_req->list);
> + kfree(pm_qos_req);
> spin_unlock_irqrestore(&pm_qos_lock, flags);
> - if (pending_update)
> - update_target(pm_qos_class);
> + update_target(qos_class);
> }
> -EXPORT_SYMBOL_GPL(pm_qos_remove_requirement);
> +EXPORT_SYMBOL_GPL(pm_qos_remove_request);
>
> /**
> * pm_qos_add_notifier - sets notification entry for changes to target value
> @@ -313,7 +302,7 @@ EXPORT_SYMBOL_GPL(pm_qos_remove_requirement);
> * will register the notifier into a notification chain that gets called
> * upon changes to the pm_qos_class target value.
> */
> - int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
> +int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
> {
> int retval;
>
> @@ -343,21 +332,16 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
> }
> EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
>
> -#define PID_NAME_LEN 32
> -
> static int pm_qos_power_open(struct inode *inode, struct file *filp)
> {
> - int ret;
> long pm_qos_class;
> - char name[PID_NAME_LEN];
>
> pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
> if (pm_qos_class >= 0) {
> - filp->private_data = (void *)pm_qos_class;
> - snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
> - ret = pm_qos_add_requirement(pm_qos_class, name,
> - PM_QOS_DEFAULT_VALUE);
> - if (ret >= 0)
> + filp->private_data = (void *) pm_qos_add_request(pm_qos_class,
> + PM_QOS_DEFAULT_VALUE);
> +
> + if (filp->private_data)
> return 0;
> }
> return -EPERM;
> @@ -365,32 +349,40 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
>
> static int pm_qos_power_release(struct inode *inode, struct file *filp)
> {
> - int pm_qos_class;
> - char name[PID_NAME_LEN];
> + struct pm_qos_request_list *req;
>
> - pm_qos_class = (long)filp->private_data;
> - snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
> - pm_qos_remove_requirement(pm_qos_class, name);
> + req = (struct pm_qos_request_list *)filp->private_data;
> + pm_qos_remove_request(req);
>
> return 0;
> }
>
> +
> static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
> size_t count, loff_t *f_pos)
> {
> s32 value;
> - int pm_qos_class;
> - char name[PID_NAME_LEN];
> -
> - pm_qos_class = (long)filp->private_data;
> - if (count != sizeof(s32))
> + int x;
> + char ascii_value[11];
> + struct pm_qos_request_list *pm_qos_req;
> +
> + if (count == sizeof(s32)) {
> + if (copy_from_user(&value, buf, sizeof(s32)))
> + return -EFAULT;
> + } else if (count == 11) { /* len('0x12345678/0') */
> + if (copy_from_user(ascii_value, buf, 11))
> + return -EFAULT;
> + x = sscanf(ascii_value, "%x", &value);
> + if (x != 1)
> + return -EINVAL;
> + pr_debug(KERN_ERR "%s, %d, 0x%x\n", ascii_value, x, value);
> + } else
> return -EINVAL;
> - if (copy_from_user(&value, buf, sizeof(s32)))
> - return -EFAULT;
> - snprintf(name, PID_NAME_LEN, "process_%d", current->pid);
> - pm_qos_update_requirement(pm_qos_class, name, value);
>
> - return sizeof(s32);
> + pm_qos_req = (struct pm_qos_request_list *)filp->private_data;
> + pm_qos_update_request(pm_qos_req, value);
> +
> + return count;
> }
>
>
> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> index 358226f..3deaac3 100644
> --- a/net/mac80211/mlme.c
> +++ b/net/mac80211/mlme.c
> @@ -507,7 +507,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
> s32 beaconint_us;
>
> if (latency < 0)
> - latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
> + latency = pm_qos_request(PM_QOS_NETWORK_LATENCY);
>
> beaconint_us = ieee80211_tu_to_usec(
> found->vif.bss_conf.beacon_int);
> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> index 8bc961f..be52bb8 100644
> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -510,7 +510,7 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
> bad_latency = time_after(jiffies +
> ieee80211_scan_get_channel_time(next_chan),
> local->leave_oper_channel_time +
> - usecs_to_jiffies(pm_qos_requirement(PM_QOS_NETWORK_LATENCY)));
> + usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));
>
> listen_int_exceeded = time_after(jiffies +
> ieee80211_scan_get_channel_time(next_chan),
> diff --git a/sound/core/pcm.c b/sound/core/pcm.c
> index 0d428d0..cbe815d 100644
> --- a/sound/core/pcm.c
> +++ b/sound/core/pcm.c
> @@ -648,9 +648,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
> substream->number = idx;
> substream->stream = stream;
> sprintf(substream->name, "subdevice #%i", idx);
> - snprintf(substream->latency_id, sizeof(substream->latency_id),
> - "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device,
> - (stream ? 'c' : 'p'), idx);
> substream->buffer_bytes_max = UINT_MAX;
> if (prev == NULL)
> pstr->substream = substream;
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index c22ebb0..1bb0e23 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -481,11 +481,13 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
> snd_pcm_timer_resolution_change(substream);
> runtime->status->state = SNDRV_PCM_STATE_SETUP;
>
> - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
> - substream->latency_id);
> + if (substream->latency_pm_qos_req) {
> + pm_qos_remove_request(substream->latency_pm_qos_req);
> + substream->latency_pm_qos_req = NULL;
> + }
> if ((usecs = period_to_usecs(runtime)) >= 0)
> - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
> - substream->latency_id, usecs);
> + substream->latency_pm_qos_req = pm_qos_add_request(
> + PM_QOS_CPU_DMA_LATENCY, usecs);
> return 0;
> _error:
> /* hardware might be unuseable from this time,
> @@ -540,8 +542,8 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
> if (substream->ops->hw_free)
> result = substream->ops->hw_free(substream);
> runtime->status->state = SNDRV_PCM_STATE_OPEN;
> - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
> - substream->latency_id);
> + pm_qos_remove_request(substream->latency_pm_qos_req);
> + substream->latency_pm_qos_req = NULL;
> return result;
> }
>
>
^ permalink raw reply
* Re: possible off by one error in drivers/isdn/divert/divert_procfs.c
From: Karsten Keil @ 2010-04-30 22:12 UTC (permalink / raw)
To: d binderman; +Cc: netdev
In-Reply-To: <BLU108-W15F33D55974CB43800BEB59C000@phx.gbl>
On Freitag, 30. April 2010 23:15:17 d binderman wrote:
> Hello there,
>
> I've just been looking at the Linux kernel linux-2.6.34-rc6. I notice the
> source code in file drivers/isdn/divert/divert_procfs.c, around line 50 is
>
> if (!(ib = kmalloc(sizeof(struct divert_info) + strlen(cp),
> GFP_ATOMIC))) return; /* no memory */
> strcpy(ib->info_start, cp); /* set output string */
>
>
> Shouldn't that be
>
> if (!(ib = kmalloc(sizeof(struct divert_info) + strlen(cp) + 1,
> GFP_ATOMIC))) return; /* no memory */
> strcpy(ib->info_start, cp); /* set output string */
>
> +1 for the zero byte ?
>
No the struct divert_info already add 2 bytes as size of the info_start field.
So in real it has one byte more as needed.
Same think with the code in drivers/isdn/divert/divert_procfs.c
Karsten
^ permalink raw reply
* Re: [RFC] BPF program access to transport header
From: Paul LeoNerd Evans @ 2010-04-30 22:10 UTC (permalink / raw)
To: Patrick McHardy, netdev
In-Reply-To: <4BDB3A4D.5020507@trash.net>
[-- Attachment #1: Type: text/plain, Size: 2044 bytes --]
On Fri, Apr 30, 2010 at 10:15:09PM +0200, Patrick McHardy wrote:
> > I forsee a number of issues with trying to provide this:
> >
> > * How to provide the protocol number (e.g. 6 for TCP, 1 for ICMP) to
> > the BPF program
>
> Using one of the registers?
Using, how? What operation would put the numbers in there in the first
place?
I was thinking more of simply providing an ancilliary data area field,
similar to SKF_AD_PROTO and SKF_AD_HATYPE, following along the same
idea.
LD WORD[SKF_AD_TRANSPROTO]
would then load the A register with the transport protocol number.
> > * How to obtain the transport offset - AIUI, the skf_transport_offset()
> > won't actually be set yet by the time the filter program runs.
>
> For IPv4 its trivial. For IPv6 you could use ipv6_skip_exthdr().
> A slightly more flexible way would be to use something like the
> netfilter ipv6_find_hdr() function to get the offset of any header
> type. The protocol number could be returned in one of the registers
> (the other one would contain the offset).
I sortof meant in general. I really don't think trying to add
IPv4/IPv6-specific code into net/core/filter.c is going to go down well.
On the other hand, I observe from casual experimentation, that on
receipt of a TCP packet in IPv4 over ethernet, the offets are:
mac=0 network=14 transport=14
This suggests more work needing to be done somewhere, because I'd expect
for an Ethernet/IPv4/TCP packet to get
mac=0 network=14 transport=34
> > * What to do if the underlying protocol doesn't support a transport
> > layer above it - e.g. ARP.
>
> I'd say simply abort the filter.
That sounds reasonable.
Another question occurs:
* How to obtain the transport protocol number? I can easily provide it
in the AD area; say as SKF_AD_TRANSPROTO; but how can
net/core/filter.c know the value?
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk
ICQ# 4135350 | Registered Linux# 179460
http://www.leonerd.org.uk/
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* Re: ixgbe and mac-vlans problem
From: Ben Greear @ 2010-04-30 22:04 UTC (permalink / raw)
To: Tantilov, Emil S; +Cc: Arnd Bergmann, NetDev, Patrick McHardy
In-Reply-To: <EA929A9653AAE14F841771FB1DE5A1365FE55609F0@rrsmsx501.amr.corp.intel.com>
On 04/30/2010 02:13 PM, Tantilov, Emil S wrote:
>> I will double-check the NIC chipset on the system that showed the
>> problem yesterday.
>
> I ran a quick test in my setup with 82599 and was able to pass traffic
> on all 50 mac-vlans without issues. This is on net-next.
I attempted this on an 82598 system, and it reproduces the problem
for me, so I think that must be what the customer was using as well
(I haven't gotten access to their system again, yet)
I created 50 mac-vlans on eth11, but it does NOT go PROMISC
mode as far as I can tell. Only 14 of the mac-vlans are
working. I'm using 64kbps UDP streams, 1k packets (ie, light load).
[root@i7-1qc-1 lanforge]# cat /sys/class/net/eth11/flags
0x1003
[root@i7-1qc-1 lanforge]# ip link show dev eth11
2: eth11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:e0:ed:11:25:12 brd ff:ff:ff:ff:ff:ff
I put it into promisc mode and now they all work:
[root@i7-1qc-1 lanforge]# ip link show dev eth11
2: eth11: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:e0:ed:11:25:12 brd ff:ff:ff:ff:ff:ff
[root@i7-1qc-1 lanforge]# cat /sys/class/net/eth11/flags
0x1103
This is on a slightly modified 2.6.31.12 kernel. I haven't had a chance to try
this on a more recent kernel yet.
lspci:
03:00.0 Ethernet controller: Intel Corporation 82598EB 10 Gigabit AF Dual Port Network Connection (rev 01)
03:00.1 Ethernet controller: Intel Corporation 82598EB 10 Gigabit AF Dual Port Network Connection
Please let me know if I can offer any additional information. It will probably take a few days before I can
get the .34 kernel in testing.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH linux-next v4 2/2] ixgbe: Example usage of the new IRQ affinity_hint callback
From: Peter P Waskiewicz Jr @ 2010-04-30 21:51 UTC (permalink / raw)
To: Thomas Gleixner
Cc: davem@davemloft.net, arjan@linux.jf.intel.com,
bhutchings@solarflare.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <alpine.LFD.2.00.1004302346030.2951@localhost.localdomain>
On Fri, 30 Apr 2010, Thomas Gleixner wrote:
> On Fri, 30 Apr 2010, Peter P Waskiewicz Jr wrote:
>> + for (i = 0; i < num_q_vectors; i++) {
>> + struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
>> + /* release the CPU mask memory */
>> + free_cpumask_var(q_vector->affinity_mask);
>> + /* clear the affinity_mask in the IRQ descriptor */
>> + irq_set_affinity_hint(adapter->msix_entries[i].vector, NULL);
>
> Freeing the mask _AFTER_ clearing the hint might be a worthwhile
> exercise :)
Crap. I had it reversed before, then when I dropped the unregister call
it got swapped. I'll fix it on the official submission for this one.
This patch is just an example patch, not to be merged just now. Once the
IRQ side is merged, and DaveM has that pulled into a tree, I'll send an
official ixgbe patch using the API. But I'll be sure to have this fixed
before sending. :-)
-PJ
^ permalink raw reply
* [patch 12/13] KS8851: Use the ks8851.h header to hold union ks8851_tx_hdr
From: Ben Dooks @ 2010-04-29 23:16 UTC (permalink / raw)
To: netdev; +Cc: tristram.ha, support
In-Reply-To: <20100429231621.015936077@fluff.org.uk>
[-- Attachment #1: ks8851-reduce-header-duplication3.patch --]
[-- Type: text/plain, Size: 3035 bytes --]
The union ks8851_tx_hdr turns up in both ks8851.c and ks8851_mll.c in two
different formats, thus making a common version in ks8851.h is going to
save source file usage.
The ks8851_mll.c uses the name ks_tx_hdr instead of ks8851_tx_hdr, so
rename this instance.
Signed-off-by: Ben Dooks <ben@simtec.co.uk>
---
---
drivers/net/ks8851.c | 13 -------------
drivers/net/ks8851.h | 14 ++++++++++++++
drivers/net/ks8851_mll.c | 16 +---------------
3 files changed, 15 insertions(+), 28 deletions(-)
Index: b/drivers/net/ks8851.c
===================================================================
--- a/drivers/net/ks8851.c 2010-04-29 01:25:54.217027162 +0900
+++ b/drivers/net/ks8851.c 2010-04-29 01:28:32.719525804 +0900
@@ -46,19 +46,6 @@ struct ks8851_rxctrl {
u16 rxcr2;
};
-/**
- * union ks8851_tx_hdr - tx header data
- * @txb: The header as bytes
- * @txw: The header as 16bit, little-endian words
- *
- * A dual representation of the tx header data to allow
- * access to individual bytes, and to allow 16bit accesses
- * with 16bit alignment.
- */
-union ks8851_tx_hdr {
- u8 txb[6];
- __le16 txw[3];
-};
/**
* struct ks8851_net - KS8851 driver private data
Index: b/drivers/net/ks8851.h
===================================================================
--- a/drivers/net/ks8851.h 2010-04-29 01:26:03.329527219 +0900
+++ b/drivers/net/ks8851.h 2010-04-29 01:26:04.169526711 +0900
@@ -323,3 +323,17 @@
#define KS_SPIOP_WR (0x40)
#define KS_SPIOP_RXFIFO (0x80)
#define KS_SPIOP_TXFIFO (0xC0)
+
+/**
+ * union ks8851_tx_hdr - tx header data
+ * @txb: The header as bytes
+ * @txw: The header as 16bit, little-endian words
+ *
+ * A dual representation of the tx header data to allow
+ * access to individual bytes, and to allow 16bit accesses
+ * with 16bit alignment.
+ */
+union ks8851_tx_hdr {
+ u8 txb[6];
+ __le16 txw[3];
+};
Index: b/drivers/net/ks8851_mll.c
===================================================================
--- a/drivers/net/ks8851_mll.c 2010-04-29 01:26:03.329527219 +0900
+++ b/drivers/net/ks8851_mll.c 2010-04-29 01:26:04.169526711 +0900
@@ -73,20 +73,6 @@ static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0
#define MAC_ADDR_LEN 6
/**
- * union ks_tx_hdr - tx header data
- * @txb: The header as bytes
- * @txw: The header as 16bit, little-endian words
- *
- * A dual representation of the tx header data to allow
- * access to individual bytes, and to allow 16bit accesses
- * with 16bit alignment.
- */
-union ks_tx_hdr {
- u8 txb[4];
- __le16 txw[2];
-};
-
-/**
* struct ks_net - KS8851 driver private data
* @net_device : The network device we're bound to
* @hw_addr : start address of data register.
@@ -138,7 +124,7 @@ struct ks_net {
struct net_device *netdev;
void __iomem *hw_addr;
void __iomem *hw_addr_cmd;
- union ks_tx_hdr txh ____cacheline_aligned;
+ union ks8851_tx_hdr txh ____cacheline_aligned;
struct mutex lock; /* spinlock to be interrupt safe */
struct platform_device *pdev;
struct mii_if_info mii;
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox