* Re: [GIT] Networking
From: David Miller @ 2013-02-08 21:57 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel, romieu, nic_swsd
In-Reply-To: <CA+55aFx81-GGEEXx+MqJvwJsDoBMMqSN80=J8LmN-Ufu4+kKcw@mail.gmail.com>
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Sat, 9 Feb 2013 08:00:39 +1100
> However, there's still the r8169 regressions (see the emails with the
> subject "regression: NETDEV WATCHDOG: eth0 (r8169): transmit queue 0
> timed out"). It's bisected, and a revert is reported to fix things.
> It's not in this pull request. Comments?
We're waiting for Hayes Wang, the author and the person most
knowledgable about those changes, to respond.
If I don't hear anything by next Weds I'll simply revert the
suspect changes.
^ permalink raw reply
* Re: [patch net-next v2 10/11] act_police: improved accuracy at high rates
From: Jiri Pirko @ 2013-02-08 22:16 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, davem, edumazet, jhs, kuznet, j.vimal
In-Reply-To: <1360350755.28557.108.camel@edumazet-glaptop>
Fri, Feb 08, 2013 at 08:12:35PM CET, eric.dumazet@gmail.com wrote:
>On Fri, 2013-02-08 at 19:59 +0100, Jiri Pirko wrote:
>> Current act_police uses rate table computed by the "tc" userspace program,
>> which has the following issue:
>>
>> The rate table has 256 entries to map packet lengths to
>> token (time units). With TSO sized packets, the 256 entry granularity
>> leads to loss/gain of rate, making the token bucket inaccurate.
>>
>> Thus, instead of relying on rate table, this patch explicitly computes
>> the time and accounts for packet transmission times with nanosecond
>> granularity.
>>
>> This is a followup to 56b765b79e9a78dc7d3f8850ba5e5567205a3ecd
>>
>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>> ---
>> net/sched/act_police.c | 119 +++++++++++++++++++++++--------------------------
>> 1 file changed, 57 insertions(+), 62 deletions(-)
>>
>> diff --git a/net/sched/act_police.c b/net/sched/act_police.c
>> index 378a649..8723183 100644
>> --- a/net/sched/act_police.c
>> +++ b/net/sched/act_police.c
>> @@ -26,20 +26,19 @@ struct tcf_police {
>> struct tcf_common common;
>> int tcfp_result;
>> u32 tcfp_ewma_rate;
>> - u32 tcfp_burst;
>> + s64 tcfp_burst;
>> u32 tcfp_mtu;
>> - u32 tcfp_toks;
>> - u32 tcfp_ptoks;
>> + s64 tcfp_toks;
>> + s64 tcfp_ptoks;
>> psched_time_t tcfp_t_c;
>> - struct qdisc_rate_table *tcfp_R_tab;
>> - struct qdisc_rate_table *tcfp_P_tab;
>> + struct psched_ratecfg rate;
>> + bool rate_present;
>> + struct psched_ratecfg peak;
>> + bool peak_present;
>> };
>> #define to_police(pc) \
>> container_of(pc, struct tcf_police, common)
>>
>> -#define L2T(p, L) qdisc_l2t((p)->tcfp_R_tab, L)
>> -#define L2T_P(p, L) qdisc_l2t((p)->tcfp_P_tab, L)
>> -
>> #define POL_TAB_MASK 15
>> static struct tcf_common *tcf_police_ht[POL_TAB_MASK + 1];
>> static u32 police_idx_gen;
>> @@ -123,10 +122,6 @@ static void tcf_police_destroy(struct tcf_police *p)
>> write_unlock_bh(&police_lock);
>> gen_kill_estimator(&p->tcf_bstats,
>> &p->tcf_rate_est);
>> - if (p->tcfp_R_tab)
>> - qdisc_put_rtab(p->tcfp_R_tab);
>> - if (p->tcfp_P_tab)
>> - qdisc_put_rtab(p->tcfp_P_tab);
>> /*
>> * gen_estimator est_timer() might access p->tcf_lock
>> * or bstats, wait a RCU grace period before freeing p
>> @@ -154,7 +149,6 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla,
>> struct nlattr *tb[TCA_POLICE_MAX + 1];
>> struct tc_police *parm;
>> struct tcf_police *police;
>> - struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
>> int size;
>>
>> if (nla == NULL)
>> @@ -197,21 +191,37 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla,
>> if (bind)
>> police->tcf_bindcnt = 1;
>> override:
>> + spin_lock_bh(&police->tcf_lock);
>> + police->tcfp_mtu = parm->mtu;
>> + police->rate_present = false;
>> + police->peak_present = false;
>> if (parm->rate.rate) {
>> + struct qdisc_rate_table *tab;
>> +
>> err = -ENOMEM;
>> - R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]);
>> - if (R_tab == NULL)
>> - goto failure;
>> + tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]);
>
>This patch was not tested, it cannot possibly work
>
>spin_lock_bh();
>rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);
>
>should crash or complain loudly.
Thanks, you are right, I had this debug option disabled. Will repost.
>
>
^ permalink raw reply
* Re: [PATCH 1/1] eventfd: implementation of EFD_MASK flag
From: Eric Wong @ 2013-02-08 22:21 UTC (permalink / raw)
To: Martin Sustrik
Cc: Andrew Morton, Alexander Viro, Sha Zhengju, linux-fsdevel,
linux-kernel, netdev
In-Reply-To: <5114F2D8.5020300@250bpm.com>
Martin Sustrik <sustrik@250bpm.com> wrote:
> On 07/02/13 23:44, Andrew Morton wrote:
> >That's a nice changelog but it omitted a critical thing: why do you
> >think the kernel needs this feature? What's the value and use case for
> >being able to poll these descriptors?
>
> To address the question, I've written down detailed description of
> the challenges of the network protocol development in user space and
> how the proposed feature addresses the problems.
>
> It's too long to fit into ChangeLog, but it may be worth reading
> when trying to judge the merit of the patch.
>
> It can be found here: http://www.250bpm.com/blog:16
Using one eventfd per userspace socket still seems a bit wasteful.
Couldn't you use a single pipe for all sockets and write the efd_mask to
the pipe for each socket?
A read from the pipe would behave like epoll_wait.
You might need to use one-shot semantics; but that's probably
the easiest thing in multithreaded apps anyways.
^ permalink raw reply
* Re: [PATCH] skbuff: Move definition of NETDEV_FRAG_PAGE_MAX_SIZE
From: David Miller @ 2013-02-08 22:34 UTC (permalink / raw)
To: alexander.h.duyck; +Cc: netdev, eric.dumazet, jeffrey.t.kirsher
In-Reply-To: <20130208201710.27890.52546.stgit@ahduyck-cp1.jf.intel.com>
From: Alexander Duyck <alexander.h.duyck@intel.com>
Date: Fri, 08 Feb 2013 12:17:15 -0800
> In order to address the fact that some devices cannot support the full 32K
> frag size we need to have the value accessible somewhere so that we can use it
> to do comparisons against what the device can support. As such I am moving
> the values out of skbuff.c and into skbuff.h.
>
> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Applied, thanks.
Although it was obvious to me due to context, please annotate your
subject lines with the target GIT tree as in "[PATCH net-next]: ..."
in the future.
Thanks.
^ permalink raw reply
* Re: [PATCH V3] bgmac: validate (and random if needed) MAC addr
From: David Miller @ 2013-02-08 22:42 UTC (permalink / raw)
To: zajec5; +Cc: netdev, florian
In-Reply-To: <1360232837-29696-1-git-send-email-zajec5@gmail.com>
From: Rafał Miłecki <zajec5@gmail.com>
Date: Thu, 7 Feb 2013 11:27:17 +0100
> This adds check for a valid Ethernet MAC address and in case it is not,
> it will generate a valid random one, such that the adapter is still
> usable.
>
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH V2] bgmac: fix "cmdcfg" calls for promisc and loopback modes
From: David Miller @ 2013-02-08 22:44 UTC (permalink / raw)
To: zajec5; +Cc: netdev, nlhintz
In-Reply-To: <1360251638-20925-1-git-send-email-zajec5@gmail.com>
From: Rafał Miłecki <zajec5@gmail.com>
Date: Thu, 7 Feb 2013 16:40:38 +0100
> The last (bool) parameter in bgmac_cmdcfg_maskset says if the write
> should be made, even if value didn't change. Currently driver doesn't
> match the specs about (not) forcing some changes. This makes it follow
> them.
>
> Reported-by: Nathan Hintz <nlhintz@hotmail.com>
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH] drivers: net: Remove remaining alloc/OOM messages
From: David Miller @ 2013-02-08 22:45 UTC (permalink / raw)
To: joe-6d6DIl74uiNBDgjK7y7TUQ
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-can-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
e1000-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
ath9k-devel-xDcbHBWguxHbcTqmT+pZeQ,
wil6210-A+ZNKFmMK5xy9aJCnZT0Uw,
brcm80211-dev-list-dY08KVG/lbpWk0Htik3J/w,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
In-Reply-To: <1360273587.27863.15.camel@joe-AO722>
From: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
Date: Thu, 07 Feb 2013 13:46:27 -0800
> alloc failures already get standardized OOM
> messages and a dump_stack.
>
> For the affected mallocs around these OOM messages:
>
> Converted kmallocs with multiplies to kmalloc_array.
> Converted a kmalloc/memcpy to kmemdup.
> Removed now unused stack variables.
> Removed unnecessary parentheses.
> Neatened alignment.
>
> Signed-off-by: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
Applied, thanks Joe.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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
* Re: [PATCH v5 04/45] percpu_rwlock: Implement the core design of Per-CPU Reader-Writer Locks
From: Paul E. McKenney @ 2013-02-08 22:47 UTC (permalink / raw)
To: Namhyung Kim
Cc: Srivatsa S. Bhat, Tejun Heo, tglx, peterz, oleg, rusty, mingo,
akpm, rostedt, wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux,
nikunj, linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev,
netdev, linux-doc, linux-kernel, walken
In-Reply-To: <87ip6gutsq.fsf@sejong.aot.lge.com>
On Tue, Jan 29, 2013 at 08:12:37PM +0900, Namhyung Kim wrote:
> On Thu, 24 Jan 2013 10:00:04 +0530, Srivatsa S. Bhat wrote:
> > On 01/24/2013 01:27 AM, Tejun Heo wrote:
> >> On Thu, Jan 24, 2013 at 01:03:52AM +0530, Srivatsa S. Bhat wrote:
> >>> CPU 0 CPU 1
> >>>
> >>> read_lock(&rwlock)
> >>>
> >>> write_lock(&rwlock) //spins, because CPU 0
> >>> //has acquired the lock for read
> >>>
> >>> read_lock(&rwlock)
> >>> ^^^^^
> >>> What happens here? Does CPU 0 start spinning (and hence deadlock) or will
> >>> it continue realizing that it already holds the rwlock for read?
> >>
> >> I don't think rwlock allows nesting write lock inside read lock.
> >> read_lock(); write_lock() will always deadlock.
> >>
> >
> > Sure, I understand that :-) My question was, what happens when *two* CPUs
> > are involved, as in, the read_lock() is invoked only on CPU 0 whereas the
> > write_lock() is invoked on CPU 1.
> >
> > For example, the same scenario shown above, but with slightly different
> > timing, will NOT result in a deadlock:
> >
> > Scenario 2:
> > CPU 0 CPU 1
> >
> > read_lock(&rwlock)
> >
> >
> > read_lock(&rwlock) //doesn't spin
> >
> > write_lock(&rwlock) //spins, because CPU 0
> > //has acquired the lock for read
> >
> >
> > So I was wondering whether the "fairness" logic of rwlocks would cause
> > the second read_lock() to spin (in the first scenario shown above) because
> > a writer is already waiting (and hence new readers should spin) and thus
> > cause a deadlock.
>
> In my understanding, current x86 rwlock does basically this (of course,
> in an atomic fashion):
>
>
> #define RW_LOCK_BIAS 0x10000
>
> rwlock_init(rwlock)
> {
> rwlock->lock = RW_LOCK_BIAS;
> }
>
> arch_read_lock(rwlock)
> {
> retry:
> if (--rwlock->lock >= 0)
> return;
>
> rwlock->lock++;
> while (rwlock->lock < 1)
> continue;
>
> goto retry;
> }
>
> arch_write_lock(rwlock)
> {
> retry:
> if ((rwlock->lock -= RW_LOCK_BIAS) == 0)
> return;
>
> rwlock->lock += RW_LOCK_BIAS;
> while (rwlock->lock != RW_LOCK_BIAS)
> continue;
>
> goto retry;
> }
>
>
> So I can't find where the 'fairness' logic comes from..
I looked through several of the rwlock implementations, and in all of
them the writer backs off if it sees readers -- or refrains from asserting
ownership of the lock to begin with.
So it should be OK to use rwlock as shown in the underlying patch.
Thanx, Paul
^ permalink raw reply
* Re: [GIT] Networking
From: Francois Romieu @ 2013-02-08 22:50 UTC (permalink / raw)
To: Linus Torvalds
Cc: David Miller, Andrew Morton, Network Development,
Linux Kernel Mailing List, Hayes Wang, Jörg Otte
In-Reply-To: <CA+55aFx81-GGEEXx+MqJvwJsDoBMMqSN80=J8LmN-Ufu4+kKcw@mail.gmail.com>
Linus Torvalds <torvalds@linux-foundation.org> :
[...]
> However, there's still the r8169 regressions (see the emails with the
> subject "regression: NETDEV WATCHDOG: eth0 (r8169): transmit queue 0
> timed out"). It's bisected, and a revert is reported to fix things.
> It's not in this pull request. Comments ?
Jörg asked Hayes. Hayes suggested to revert. Francois reverts, fixes a
pair of rejects, builds, boot. Anyone should be able to pull from
branch 'davem.r8169' in repository
git://violet.fr.zoreil.com/romieu/linux davem.r8169
to get the changes below :
Distance from 'davem' (a1c83b054ebe1264ed9ae9d5c286f9eae68e60ea)
----------------------------------------------------------------
4521e1a94279ce610d3f9b7945c17d581f804242
eef63cc1c6ecf4898a973f870aec95d6e923ea77
Diffstat
--------
drivers/net/ethernet/realtek/r8169.c | 86 ++++++++----------------------------
1 file changed, 19 insertions(+), 67 deletions(-)
Shortlog
--------
Francois Romieu (2):
Revert "r8169: enable ALDPS for power saving".
Revert "r8169: enable internal ASPM and clock request settings".
Patch
-----
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 1170232..998974f 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -450,7 +450,6 @@ enum rtl8168_registers {
#define PWM_EN (1 << 22)
#define RXDV_GATED_EN (1 << 19)
#define EARLY_TALLY_EN (1 << 16)
-#define FORCE_CLK (1 << 15) /* force clock request */
};
enum rtl_register_content {
@@ -514,7 +513,6 @@ enum rtl_register_content {
PMEnable = (1 << 0), /* Power Management Enable */
/* Config2 register p. 25 */
- ClkReqEn = (1 << 7), /* Clock Request Enable */
MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */
PCI_Clock_66MHz = 0x01,
PCI_Clock_33MHz = 0x00,
@@ -535,7 +533,6 @@ enum rtl_register_content {
Spi_en = (1 << 3),
LanWake = (1 << 1), /* LanWake enable/disable */
PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */
- ASPM_en = (1 << 0), /* ASPM enable */
/* TBICSR p.28 */
TBIReset = 0x80000000,
@@ -684,7 +681,6 @@ enum features {
RTL_FEATURE_WOL = (1 << 0),
RTL_FEATURE_MSI = (1 << 1),
RTL_FEATURE_GMII = (1 << 2),
- RTL_FEATURE_FW_LOADED = (1 << 3),
};
struct rtl8169_counters {
@@ -2389,10 +2385,8 @@ static void rtl_apply_firmware(struct rtl8169_private *tp)
struct rtl_fw *rtl_fw = tp->rtl_fw;
/* TODO: release firmware once rtl_phy_write_fw signals failures. */
- if (!IS_ERR_OR_NULL(rtl_fw)) {
+ if (!IS_ERR_OR_NULL(rtl_fw))
rtl_phy_write_fw(tp, rtl_fw);
- tp->features |= RTL_FEATURE_FW_LOADED;
- }
}
static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)
@@ -2403,31 +2397,6 @@ static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)
rtl_apply_firmware(tp);
}
-static void r810x_aldps_disable(struct rtl8169_private *tp)
-{
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, 0x18, 0x0310);
- msleep(100);
-}
-
-static void r810x_aldps_enable(struct rtl8169_private *tp)
-{
- if (!(tp->features & RTL_FEATURE_FW_LOADED))
- return;
-
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, 0x18, 0x8310);
-}
-
-static void r8168_aldps_enable_1(struct rtl8169_private *tp)
-{
- if (!(tp->features & RTL_FEATURE_FW_LOADED))
- return;
-
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_w1w0_phy(tp, 0x15, 0x1000, 0x0000);
-}
-
static void rtl8169s_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
@@ -3218,8 +3187,6 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400);
rtl_writephy(tp, 0x1f, 0x0000);
- r8168_aldps_enable_1(tp);
-
/* Broken BIOS workaround: feed GigaMAC registers with MAC address. */
rtl_rar_exgmac_set(tp, tp->dev->dev_addr);
}
@@ -3294,8 +3261,6 @@ static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x05, 0x8b85);
rtl_w1w0_phy(tp, 0x06, 0x4000, 0x0000);
rtl_writephy(tp, 0x1f, 0x0000);
-
- r8168_aldps_enable_1(tp);
}
static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp)
@@ -3303,8 +3268,6 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp)
rtl_apply_firmware(tp);
rtl8168f_hw_phy_config(tp);
-
- r8168_aldps_enable_1(tp);
}
static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
@@ -3402,8 +3365,6 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001);
rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400);
rtl_writephy(tp, 0x1f, 0x0000);
-
- r8168_aldps_enable_1(tp);
}
static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
@@ -3489,19 +3450,21 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp)
};
/* Disable ALDPS before ram code */
- r810x_aldps_disable(tp);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x18, 0x0310);
+ msleep(100);
rtl_apply_firmware(tp);
rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
-
- r810x_aldps_enable(tp);
}
static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
{
/* Disable ALDPS before setting firmware */
- r810x_aldps_disable(tp);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x18, 0x0310);
+ msleep(20);
rtl_apply_firmware(tp);
@@ -3511,8 +3474,6 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x10, 0x401f);
rtl_writephy(tp, 0x19, 0x7030);
rtl_writephy(tp, 0x1f, 0x0000);
-
- r810x_aldps_enable(tp);
}
static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
@@ -3525,7 +3486,9 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
};
/* Disable ALDPS before ram code */
- r810x_aldps_disable(tp);
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x18, 0x0310);
+ msleep(100);
rtl_apply_firmware(tp);
@@ -3533,8 +3496,6 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
-
- r810x_aldps_enable(tp);
}
static void rtl_hw_phy_config(struct net_device *dev)
@@ -5051,6 +5012,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
RTL_W8(MaxTxPacketSize, EarlySize);
+ rtl_disable_clock_request(pdev);
+
RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
@@ -5059,8 +5022,7 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
RTL_W32(MISC, RTL_R32(MISC) | PWM_EN);
- RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en);
- RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
+ RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);
}
static void rtl_hw_start_8168f(struct rtl8169_private *tp)
@@ -5085,12 +5047,13 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp)
RTL_W8(MaxTxPacketSize, EarlySize);
+ rtl_disable_clock_request(pdev);
+
RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
- RTL_W32(MISC, RTL_R32(MISC) | PWM_EN | FORCE_CLK);
- RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en);
- RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
+ RTL_W32(MISC, RTL_R32(MISC) | PWM_EN);
+ RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);
}
static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
@@ -5147,10 +5110,8 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
- RTL_W32(MISC, (RTL_R32(MISC) | FORCE_CLK) & ~RXDV_GATED_EN);
+ RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN);
RTL_W8(MaxTxPacketSize, EarlySize);
- RTL_W8(Config5, RTL_R8(Config5) | ASPM_en);
- RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
@@ -5366,9 +5327,6 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
- RTL_W8(Config5, RTL_R8(Config5) | ASPM_en);
- RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
- RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK);
rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
}
@@ -5394,9 +5352,6 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
- RTL_W8(Config5, RTL_R8(Config5) | ASPM_en);
- RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
- RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK);
rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402));
@@ -5418,10 +5373,7 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp)
/* Force LAN exit from ASPM if Rx/Tx are not idle */
RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800);
- RTL_W32(MISC,
- (RTL_R32(MISC) | DISABLE_LAN_EN | FORCE_CLK) & ~EARLY_TALLY_EN);
- RTL_W8(Config5, RTL_R8(Config5) | ASPM_en);
- RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn);
+ RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN);
RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
}
--
Ueimor
^ permalink raw reply related
* Re: [Patch net-next] ipv6: fix a RCU warning in net/ipv6/ip6_flowlabel.c
From: David Miller @ 2013-02-08 22:57 UTC (permalink / raw)
To: amwang; +Cc: netdev, yoshfuji
In-Reply-To: <1360288360-20385-1-git-send-email-amwang@redhat.com>
From: Cong Wang <amwang@redhat.com>
Date: Fri, 8 Feb 2013 09:52:40 +0800
> This patch fixes the following RCU warning:
>
> [ 51.680236] ===============================
> [ 51.681914] [ INFO: suspicious RCU usage. ]
> [ 51.683610] 3.8.0-rc6-next-20130206-sasha-00028-g83214f7-dirty #276 Tainted: G W
> [ 51.686703] -------------------------------
> [ 51.688281] net/ipv6/ip6_flowlabel.c:671 suspicious rcu_dereference_check() usage!
>
> we should use rcu_dereference_bh() when we hold rcu_read_lock_bh().
>
> Reported-by: Sasha Levin <sasha.levin@oracle.com>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> Signed-off-by: Cong Wang <amwang@redhat.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] macvlan: broadcast addr should be part of mc_filter
From: David Miller @ 2013-02-08 22:57 UTC (permalink / raw)
To: erdnetdev; +Cc: netdev, maze
In-Reply-To: <1360288977.28557.77.camel@edumazet-glaptop>
From: Eric Dumazet <erdnetdev@gmail.com>
Date: Thu, 07 Feb 2013 18:02:57 -0800
> From: Eric Dumazet <edumazet@google.com>
>
> commit cd431e738509e (macvlan: add multicast filter) forgot
> the broadcast case.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Maciej Żenczykowski <maze@google.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] macvlan: add a salt to mc_hash()
From: David Miller @ 2013-02-08 22:57 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, maze
In-Reply-To: <1360291262.28557.89.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 07 Feb 2013 18:41:02 -0800
> From: Eric Dumazet <edumazet@google.com>
>
> Some multicast addresses are common to all macvlans,
> so if a multicast message has a hash value collision, we
> have to deliver a copy to all macvlans, adding significant
> latency and possible packet drops if netdev_max_backlog
> limit is hit.
>
> Having a per macvlan hash function permits to reduce the
> impact of hash collisions.
>
> Suggested-by: Maciej Żenczykowski <maze@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] net: sctp: sctp_auth_make_key_vector: use sctp_auth_create_key
From: David Miller @ 2013-02-08 22:57 UTC (permalink / raw)
To: dborkman; +Cc: linux-sctp, netdev
In-Reply-To: <783e1129996c3f09c7da121f5dd91c8ac7ba5baa.1360314390.git.dborkman@redhat.com>
From: Daniel Borkmann <dborkman@redhat.com>
Date: Fri, 8 Feb 2013 10:22:58 +0100
> In sctp_auth_make_key_vector, we allocate a temporary sctp_auth_bytes
> structure with kmalloc instead of the sctp_auth_create_key allocator.
> Change this to sctp_auth_create_key as it is the case everywhere else,
> so that we also can properly free it via sctp_auth_key_put. This makes
> it easier for future code changes in the structure and allocator itself,
> since a single API is consistently used for this purpose. Also, by
> using sctp_auth_create_key we're doing sanity checks over the arguments.
>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] cxgb4vf: Fix extraction of cpl_rx_pkt from the response queue descriptor
From: David Miller @ 2013-02-08 22:57 UTC (permalink / raw)
To: vipul; +Cc: netdev, divy, dm, leedom, abhishek, jay
In-Reply-To: <1360327791-21704-1-git-send-email-vipul@chelsio.com>
From: Vipul Pandya <vipul@chelsio.com>
Date: Fri, 8 Feb 2013 18:19:51 +0530
> This was preventing GRO and RxCheckSum offload to happen.
>
> Signed-off-by: Jay Hernandez <jay@chelsio.com>
> Signed-off-by: Vipul Pandya <vipul@chelsio.com>
Applied.
^ permalink raw reply
* Re: [PATCH RFC v2 1/2] net/802: Implement Multiple Registration Protocol (MRP)
From: David Miller @ 2013-02-08 23:01 UTC (permalink / raw)
To: david.ward; +Cc: netdev, kaber, eric.dumazet
In-Reply-To: <1360295457-5245-2-git-send-email-david.ward@ll.mit.edu>
These changes look really good, please address the feedback you got
from Patrick McHardy, add his Ack, and resubmit this series.
Thank you.
^ permalink raw reply
* [PATCH] Don't allow multiple TPGs or targets to share a portal
From: Andy Grover @ 2013-02-08 23:05 UTC (permalink / raw)
To: target-devel; +Cc: netdev
In-Reply-To: <5113F5A6.80500@redhat.com>
RFC 3720 says "Each Network Portal, as utilized by a given iSCSI Node,
belongs to exactly one portal group within that node." therefore
iscsit_add_np should not check for existing matching portals, it should
just go ahead and try to make the portal, and then kernel_bind() will
return the proper error.
Signed-off-by: Andy Grover <agrover@redhat.com>
---
drivers/target/iscsi/iscsi_target.c | 64 -----------------------------------
1 files changed, 0 insertions(+), 64 deletions(-)
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 339f97f..73be05c 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -264,64 +264,6 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
return 0;
}
-static struct iscsi_np *iscsit_get_np(
- struct __kernel_sockaddr_storage *sockaddr,
- int network_transport)
-{
- struct sockaddr_in *sock_in, *sock_in_e;
- struct sockaddr_in6 *sock_in6, *sock_in6_e;
- struct iscsi_np *np;
- int ip_match = 0;
- u16 port;
-
- spin_lock_bh(&np_lock);
- list_for_each_entry(np, &g_np_list, np_list) {
- spin_lock(&np->np_thread_lock);
- if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
- spin_unlock(&np->np_thread_lock);
- continue;
- }
-
- if (sockaddr->ss_family == AF_INET6) {
- sock_in6 = (struct sockaddr_in6 *)sockaddr;
- sock_in6_e = (struct sockaddr_in6 *)&np->np_sockaddr;
-
- if (!memcmp(&sock_in6->sin6_addr.in6_u,
- &sock_in6_e->sin6_addr.in6_u,
- sizeof(struct in6_addr)))
- ip_match = 1;
-
- port = ntohs(sock_in6->sin6_port);
- } else {
- sock_in = (struct sockaddr_in *)sockaddr;
- sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
-
- if (sock_in->sin_addr.s_addr ==
- sock_in_e->sin_addr.s_addr)
- ip_match = 1;
-
- port = ntohs(sock_in->sin_port);
- }
-
- if ((ip_match == 1) && (np->np_port == port) &&
- (np->np_network_transport == network_transport)) {
- /*
- * Increment the np_exports reference count now to
- * prevent iscsit_del_np() below from being called
- * while iscsi_tpg_add_network_portal() is called.
- */
- np->np_exports++;
- spin_unlock(&np->np_thread_lock);
- spin_unlock_bh(&np_lock);
- return np;
- }
- spin_unlock(&np->np_thread_lock);
- }
- spin_unlock_bh(&np_lock);
-
- return NULL;
-}
-
struct iscsi_np *iscsit_add_np(
struct __kernel_sockaddr_storage *sockaddr,
char *ip_str,
@@ -331,12 +273,6 @@ struct iscsi_np *iscsit_add_np(
struct sockaddr_in6 *sock_in6;
struct iscsi_np *np;
int ret;
- /*
- * Locate the existing struct iscsi_np if already active..
- */
- np = iscsit_get_np(sockaddr, network_transport);
- if (np)
- return np;
np = kzalloc(sizeof(struct iscsi_np), GFP_KERNEL);
if (!np) {
--
1.7.1
^ permalink raw reply related
* Re: [PATCH v5 04/45] percpu_rwlock: Implement the core design of Per-CPU Reader-Writer Locks
From: Paul E. McKenney @ 2013-02-08 23:10 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: tglx, peterz, tj, oleg, rusty, mingo, akpm, namhyung, rostedt,
wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux, nikunj,
linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev, netdev,
linux-doc, linux-kernel
In-Reply-To: <20130122073347.13822.85876.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:03:53PM +0530, Srivatsa S. Bhat wrote:
> Using global rwlocks as the backend for per-CPU rwlocks helps us avoid many
> lock-ordering related problems (unlike per-cpu locks). However, global
> rwlocks lead to unnecessary cache-line bouncing even when there are no
> writers present, which can slow down the system needlessly.
>
> Per-cpu counters can help solve the cache-line bouncing problem. So we
> actually use the best of both: per-cpu counters (no-waiting) at the reader
> side in the fast-path, and global rwlocks in the slowpath.
>
> [ Fastpath = no writer is active; Slowpath = a writer is active ]
>
> IOW, the readers just increment/decrement their per-cpu refcounts (disabling
> interrupts during the updates, if necessary) when no writer is active.
> When a writer becomes active, he signals all readers to switch to global
> rwlocks for the duration of his activity. The readers switch over when it
> is safe for them (ie., when they are about to start a fresh, non-nested
> read-side critical section) and start using (holding) the global rwlock for
> read in their subsequent critical sections.
>
> The writer waits for every existing reader to switch, and then acquires the
> global rwlock for write and enters his critical section. Later, the writer
> signals all readers that he is done, and that they can go back to using their
> per-cpu refcounts again.
>
> Note that the lock-safety (despite the per-cpu scheme) comes from the fact
> that the readers can *choose* _when_ to switch to rwlocks upon the writer's
> signal. And the readers don't wait on anybody based on the per-cpu counters.
> The only true synchronization that involves waiting at the reader-side in this
> scheme, is the one arising from the global rwlock, which is safe from circular
> locking dependency issues.
>
> Reader-writer locks and per-cpu counters are recursive, so they can be
> used in a nested fashion in the reader-path, which makes per-CPU rwlocks also
> recursive. Also, this design of switching the synchronization scheme ensures
> that you can safely nest and use these locks in a very flexible manner.
>
> I'm indebted to Michael Wang and Xiao Guangrong for their numerous thoughtful
> suggestions and ideas, which inspired and influenced many of the decisions in
> this as well as previous designs. Thanks a lot Michael and Xiao!
Looks pretty close! Some comments interspersed below. Please either
fix the code or my confusion, as the case may be. ;-)
Thanx, Paul
> Cc: David Howells <dhowells@redhat.com>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> ---
>
> include/linux/percpu-rwlock.h | 10 +++
> lib/percpu-rwlock.c | 128 ++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 136 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/percpu-rwlock.h b/include/linux/percpu-rwlock.h
> index 8dec8fe..6819bb8 100644
> --- a/include/linux/percpu-rwlock.h
> +++ b/include/linux/percpu-rwlock.h
> @@ -68,4 +68,14 @@ extern void percpu_free_rwlock(struct percpu_rwlock *);
> __percpu_init_rwlock(pcpu_rwlock, #pcpu_rwlock, &rwlock_key); \
> })
>
> +#define reader_uses_percpu_refcnt(pcpu_rwlock, cpu) \
> + (ACCESS_ONCE(per_cpu(*((pcpu_rwlock)->reader_refcnt), cpu)))
> +
> +#define reader_nested_percpu(pcpu_rwlock) \
> + (__this_cpu_read(*((pcpu_rwlock)->reader_refcnt)) > 1)
> +
> +#define writer_active(pcpu_rwlock) \
> + (__this_cpu_read(*((pcpu_rwlock)->writer_signal)))
> +
> #endif
> +
> diff --git a/lib/percpu-rwlock.c b/lib/percpu-rwlock.c
> index 80dad93..992da5c 100644
> --- a/lib/percpu-rwlock.c
> +++ b/lib/percpu-rwlock.c
> @@ -64,21 +64,145 @@ void percpu_free_rwlock(struct percpu_rwlock *pcpu_rwlock)
>
> void percpu_read_lock(struct percpu_rwlock *pcpu_rwlock)
> {
> - read_lock(&pcpu_rwlock->global_rwlock);
> + preempt_disable();
> +
> + /* First and foremost, let the writer know that a reader is active */
> + this_cpu_inc(*pcpu_rwlock->reader_refcnt);
> +
> + /*
> + * If we are already using per-cpu refcounts, it is not safe to switch
> + * the synchronization scheme. So continue using the refcounts.
> + */
> + if (reader_nested_percpu(pcpu_rwlock)) {
> + goto out;
> + } else {
> + /*
> + * The write to 'reader_refcnt' must be visible before we
> + * read 'writer_signal'.
> + */
> + smp_mb(); /* Paired with smp_rmb() in sync_reader() */
> +
> + if (likely(!writer_active(pcpu_rwlock))) {
> + goto out;
> + } else {
> + /* Writer is active, so switch to global rwlock. */
> + read_lock(&pcpu_rwlock->global_rwlock);
> +
> + /*
> + * We might have raced with a writer going inactive
> + * before we took the read-lock. So re-evaluate whether
> + * we still need to hold the rwlock or if we can switch
> + * back to per-cpu refcounts. (This also helps avoid
> + * heterogeneous nesting of readers).
> + */
> + if (writer_active(pcpu_rwlock))
The above writer_active() can be reordered with the following this_cpu_dec(),
strange though it might seem. But this is OK because holding the rwlock
is conservative. But might be worth a comment.
> + this_cpu_dec(*pcpu_rwlock->reader_refcnt);
> + else
In contrast, no reordering can happen here because read_unlock() is
required to keep the critical section underneath the lock.
> + read_unlock(&pcpu_rwlock->global_rwlock);
> + }
> + }
> +
> +out:
> + /* Prevent reordering of any subsequent reads */
> + smp_rmb();
This should be smp_mb(). "Readers" really can do writes. Hence the
name lglock -- "local/global" rather than "reader/writer".
> }
>
> void percpu_read_unlock(struct percpu_rwlock *pcpu_rwlock)
> {
> - read_unlock(&pcpu_rwlock->global_rwlock);
We need an smp_mb() here to keep the critical section ordered before the
this_cpu_dec() below. Otherwise, if a writer shows up just after we
exit the fastpath, that writer is not guaranteed to see the effects of
our critical section. Equivalently, the prior read-side critical section
just might see some of the writer's updates, which could be a bit of
a surprise to the reader.
> + /*
> + * We never allow heterogeneous nesting of readers. So it is trivial
> + * to find out the kind of reader we are, and undo the operation
> + * done by our corresponding percpu_read_lock().
> + */
> + if (__this_cpu_read(*pcpu_rwlock->reader_refcnt)) {
> + this_cpu_dec(*pcpu_rwlock->reader_refcnt);
> + smp_wmb(); /* Paired with smp_rmb() in sync_reader() */
Given an smp_mb() above, I don't understand the need for this smp_wmb().
Isn't the idea that if the writer sees ->reader_refcnt decremented to
zero, it also needs to see the effects of the corresponding reader's
critical section?
Or am I missing something subtle here? In any case, if this smp_wmb()
really is needed, there should be some subsequent write that the writer
might observe. From what I can see, there is no subsequent write from
this reader that the writer cares about.
> + } else {
> + read_unlock(&pcpu_rwlock->global_rwlock);
> + }
> +
> + preempt_enable();
> +}
> +
> +static inline void raise_writer_signal(struct percpu_rwlock *pcpu_rwlock,
> + unsigned int cpu)
> +{
> + per_cpu(*pcpu_rwlock->writer_signal, cpu) = true;
> +}
> +
> +static inline void drop_writer_signal(struct percpu_rwlock *pcpu_rwlock,
> + unsigned int cpu)
> +{
> + per_cpu(*pcpu_rwlock->writer_signal, cpu) = false;
> +}
> +
> +static void announce_writer_active(struct percpu_rwlock *pcpu_rwlock)
> +{
> + unsigned int cpu;
> +
> + for_each_online_cpu(cpu)
> + raise_writer_signal(pcpu_rwlock, cpu);
> +
> + smp_mb(); /* Paired with smp_rmb() in percpu_read_[un]lock() */
> +}
> +
> +static void announce_writer_inactive(struct percpu_rwlock *pcpu_rwlock)
> +{
> + unsigned int cpu;
> +
> + drop_writer_signal(pcpu_rwlock, smp_processor_id());
Why do we drop ourselves twice? More to the point, why is it important to
drop ourselves first?
> +
> + for_each_online_cpu(cpu)
> + drop_writer_signal(pcpu_rwlock, cpu);
> +
> + smp_mb(); /* Paired with smp_rmb() in percpu_read_[un]lock() */
> +}
> +
> +/*
> + * Wait for the reader to see the writer's signal and switch from percpu
> + * refcounts to global rwlock.
> + *
> + * If the reader is still using percpu refcounts, wait for him to switch.
> + * Else, we can safely go ahead, because either the reader has already
> + * switched over, or the next reader that comes along on that CPU will
> + * notice the writer's signal and will switch over to the rwlock.
> + */
> +static inline void sync_reader(struct percpu_rwlock *pcpu_rwlock,
> + unsigned int cpu)
> +{
> + smp_rmb(); /* Paired with smp_[w]mb() in percpu_read_[un]lock() */
As I understand it, the purpose of this memory barrier is to ensure
that the stores in drop_writer_signal() happen before the reads from
->reader_refcnt in reader_uses_percpu_refcnt(), thus preventing the
race between a new reader attempting to use the fastpath and this writer
acquiring the lock. Unless I am confused, this must be smp_mb() rather
than smp_rmb().
Also, why not just have a single smp_mb() at the beginning of
sync_all_readers() instead of executing one barrier per CPU?
> +
> + while (reader_uses_percpu_refcnt(pcpu_rwlock, cpu))
> + cpu_relax();
> +}
> +
> +static void sync_all_readers(struct percpu_rwlock *pcpu_rwlock)
> +{
> + unsigned int cpu;
> +
> + for_each_online_cpu(cpu)
> + sync_reader(pcpu_rwlock, cpu);
> }
>
> void percpu_write_lock(struct percpu_rwlock *pcpu_rwlock)
> {
> + /*
> + * Tell all readers that a writer is becoming active, so that they
> + * start switching over to the global rwlock.
> + */
> + announce_writer_active(pcpu_rwlock);
> + sync_all_readers(pcpu_rwlock);
> write_lock(&pcpu_rwlock->global_rwlock);
> }
>
> void percpu_write_unlock(struct percpu_rwlock *pcpu_rwlock)
> {
> + /*
> + * Inform all readers that we are done, so that they can switch back
> + * to their per-cpu refcounts. (We don't need to wait for them to
> + * see it).
> + */
> + announce_writer_inactive(pcpu_rwlock);
> write_unlock(&pcpu_rwlock->global_rwlock);
> }
>
>
^ permalink raw reply
* Issue with Micrel PCI Network Driver.
From: Joseph Lutz @ 2013-02-08 23:17 UTC (permalink / raw)
To: netdev
I am having an issue with one of the network interface drivers. The
driver in question is 'drivers/net/ethernet/micrel/ksz884x.c', the
driver for the Micrel-Kendin device 8841.
I am trying to get systemd to rename the three network interfaces in my
embedded atom system. I have one of the interfaces being renamed (an
Intel Corporation 82574L), but the two Micrel interfaces are not being
renamed. I traced this down to the driver not populating the
/sys/devices/pci* information. Instead it places the driver into
/sys/devices/virtual/net/.
Here are the details of the setup I am having the problem on:
# uname -a ; lspci ; lspci -t ; ls -l /sys/class/net/
Linux orionlx 3.2.28-rt42-0.1-default+ #1 SMP PREEMPT RT Fri Feb 8
12:01:13 CST 2013 i686 GNU/Linux
00:00.0 Host bridge: Intel Corporation System Controller Hub (SCH
Poulsbo) (rev 07)
00:02.0 VGA compatible controller: Intel Corporation System
Controller Hub (SCH Poulsbo) Graphics Controller (rev 07)
00:1a.0 USB Controller: Intel Corporation System Controller Hub
(SCH Poulsbo) USB Client Controller (rev 07)
00:1b.0 Audio device: Intel Corporation System Controller Hub (SCH
Poulsbo) HD Audio Controller (rev 07)
00:1c.0 PCI bridge: Intel Corporation System Controller Hub (SCH
Poulsbo) PCI Express Port 1 (rev 07)
00:1c.1 PCI bridge: Intel Corporation System Controller Hub (SCH
Poulsbo) PCI Express Port 2 (rev 07)
00:1d.0 USB Controller: Intel Corporation System Controller Hub
(SCH Poulsbo) USB UHCI #1 (rev 07)
00:1d.1 USB Controller: Intel Corporation System Controller Hub
(SCH Poulsbo) USB UHCI #2 (rev 07)
00:1d.2 USB Controller: Intel Corporation System Controller Hub
(SCH Poulsbo) USB UHCI #3 (rev 07)
00:1d.7 USB Controller: Intel Corporation System Controller Hub
(SCH Poulsbo) USB EHCI #1 (rev 07)
00:1f.0 ISA bridge: Intel Corporation System Controller Hub (SCH
Poulsbo) LPC Bridge (rev 07)
00:1f.1 IDE interface: Intel Corporation System Controller Hub (SCH
Poulsbo) IDE Controller (rev 07)
01:00.0 PCI bridge: Pericom Semiconductor Device e111 (rev 02)
02:01.0 PCI bridge: Pericom Semiconductor
PI7C8152A/PI7C8152B/PI7C8152BI PCI-to-PCI Bridge (rev 01)
03:00.0 Ethernet controller: Micrel-Kendin Device 8841 (rev 10)
03:01.0 Ethernet controller: Micrel-Kendin Device 8841 (rev 10)
04:00.0 Ethernet controller: Intel Corporation 82574L Gigabit
Network Connection
-[0000:00]-+-00.0
+-02.0
+-1a.0
+-1b.0
+-1c.0-[0000:01-03]----00.0-[0000:02-03]----01.0-[0000:03]--+-00.0
| \-01.0
+-1c.1-[0000:04]----00.0
+-1d.0
+-1d.1
+-1d.2
+-1d.7
+-1f.0
\-1f.1
lrwxrwxrwx 1 root root 0 Mar 27 02:04 enp4s0 ->
../../devices/pci0000:00/0000:00:1c.1/0000:04:00.0/net/enp4s0
lrwxrwxrwx 1 root root 0 Mar 27 02:04 eth1 ->
../../devices/virtual/net/eth1
lrwxrwxrwx 1 root root 0 Mar 27 02:04 eth2 ->
../../devices/virtual/net/eth2
lrwxrwxrwx 1 root root 0 Mar 27 02:04 lo ->
../../devices/virtual/net/lo
This kernel is version 3.2.28 with the real-time patches applied.
If there isn't anyone available to resolve this issue I would be willing
to assist. I just do not have any experience writing Network Drivers or
PCI drivers. I have only written simple device drivers.
--
..............................................
Joseph Lutz
Software Developer
NovaTech, LLC
13555 W. 107th Street
Lenexa, KS 66215
(913) 451-1880 (main)
(913) 742-4531 (direct)
Joseph.Lutz@novatechweb.com
^ permalink raw reply
* Re: [PATCH v5 05/45] percpu_rwlock: Make percpu-rwlocks IRQ-safe, optimally
From: Paul E. McKenney @ 2013-02-08 23:44 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: tglx, peterz, tj, oleg, rusty, mingo, akpm, namhyung, rostedt,
wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux, nikunj,
linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev, netdev,
linux-doc, linux-kernel
In-Reply-To: <20130122073400.13822.52336.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:04:11PM +0530, Srivatsa S. Bhat wrote:
> If interrupt handlers can also be readers, then one of the ways to make
> per-CPU rwlocks safe, is to disable interrupts at the reader side before
> trying to acquire the per-CPU rwlock and keep it disabled throughout the
> duration of the read-side critical section.
>
> The goal is to avoid cases such as:
>
> 1. writer is active and it holds the global rwlock for write
>
> 2. a regular reader comes in and marks itself as present (by incrementing
> its per-CPU refcount) before checking whether writer is active.
>
> 3. an interrupt hits the reader;
> [If it had not hit, the reader would have noticed that the writer is
> active and would have decremented its refcount and would have tried
> to acquire the global rwlock for read].
> Since the interrupt handler also happens to be a reader, it notices
> the non-zero refcount (which was due to the reader who got interrupted)
> and thinks that this is a nested read-side critical section and
> proceeds to take the fastpath, which is wrong. The interrupt handler
> should have noticed that the writer is active and taken the rwlock
> for read.
>
> So, disabling interrupts can help avoid this problem (at the cost of keeping
> the interrupts disabled for quite long).
>
> But Oleg had a brilliant idea by which we can do much better than that:
> we can manage with disabling interrupts _just_ during the updates (writes to
> per-CPU refcounts) to safe-guard against races with interrupt handlers.
> Beyond that, we can keep the interrupts enabled and still be safe w.r.t
> interrupt handlers that can act as readers.
>
> Basically the idea is that we differentiate between the *part* of the
> per-CPU refcount that we use for reference counting vs the part that we use
> merely to make the writer wait for us to switch over to the right
> synchronization scheme.
>
> The scheme involves splitting the per-CPU refcounts into 2 parts:
> eg: the lower 16 bits are used to track the nesting depth of the reader
> (a "nested-counter"), and the remaining (upper) bits are used to merely mark
> the presence of the reader.
>
> As long as the overall reader_refcnt is non-zero, the writer waits for the
> reader (assuming that the reader is still actively using per-CPU refcounts for
> synchronization).
>
> The reader first sets one of the higher bits to mark its presence, and then
> uses the lower 16 bits to manage the nesting depth. So, an interrupt handler
> coming in as illustrated above will be able to distinguish between "this is
> a nested read-side critical section" vs "we have merely marked our presence
> to make the writer wait for us to switch" by looking at the same refcount.
> Thus, it makes it unnecessary to keep interrupts disabled throughout the
> read-side critical section, despite having the possibility of interrupt
> handlers being readers themselves.
>
>
> Implement this logic and rename the locking functions appropriately, to
> reflect what they do.
One nit below. The issues called out in the previous patch still seem
to me to apply.
Thanx, Paul
> Based-on-idea-by: Oleg Nesterov <oleg@redhat.com>
> Cc: David Howells <dhowells@redhat.com>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> ---
>
> include/linux/percpu-rwlock.h | 15 ++++++++++-----
> lib/percpu-rwlock.c | 41 +++++++++++++++++++++++++++--------------
> 2 files changed, 37 insertions(+), 19 deletions(-)
>
> diff --git a/include/linux/percpu-rwlock.h b/include/linux/percpu-rwlock.h
> index 6819bb8..856ba6b 100644
> --- a/include/linux/percpu-rwlock.h
> +++ b/include/linux/percpu-rwlock.h
> @@ -34,11 +34,13 @@ struct percpu_rwlock {
> rwlock_t global_rwlock;
> };
>
> -extern void percpu_read_lock(struct percpu_rwlock *);
> -extern void percpu_read_unlock(struct percpu_rwlock *);
> +extern void percpu_read_lock_irqsafe(struct percpu_rwlock *);
> +extern void percpu_read_unlock_irqsafe(struct percpu_rwlock *);
>
> -extern void percpu_write_lock(struct percpu_rwlock *);
> -extern void percpu_write_unlock(struct percpu_rwlock *);
> +extern void percpu_write_lock_irqsave(struct percpu_rwlock *,
> + unsigned long *flags);
> +extern void percpu_write_unlock_irqrestore(struct percpu_rwlock *,
> + unsigned long *flags);
>
> extern int __percpu_init_rwlock(struct percpu_rwlock *,
> const char *, struct lock_class_key *);
> @@ -68,11 +70,14 @@ extern void percpu_free_rwlock(struct percpu_rwlock *);
> __percpu_init_rwlock(pcpu_rwlock, #pcpu_rwlock, &rwlock_key); \
> })
>
> +#define READER_PRESENT (1UL << 16)
> +#define READER_REFCNT_MASK (READER_PRESENT - 1)
> +
> #define reader_uses_percpu_refcnt(pcpu_rwlock, cpu) \
> (ACCESS_ONCE(per_cpu(*((pcpu_rwlock)->reader_refcnt), cpu)))
>
> #define reader_nested_percpu(pcpu_rwlock) \
> - (__this_cpu_read(*((pcpu_rwlock)->reader_refcnt)) > 1)
> + (__this_cpu_read(*((pcpu_rwlock)->reader_refcnt)) & READER_REFCNT_MASK)
>
> #define writer_active(pcpu_rwlock) \
> (__this_cpu_read(*((pcpu_rwlock)->writer_signal)))
> diff --git a/lib/percpu-rwlock.c b/lib/percpu-rwlock.c
> index 992da5c..a8d177a 100644
> --- a/lib/percpu-rwlock.c
> +++ b/lib/percpu-rwlock.c
> @@ -62,19 +62,19 @@ void percpu_free_rwlock(struct percpu_rwlock *pcpu_rwlock)
> pcpu_rwlock->writer_signal = NULL;
> }
>
> -void percpu_read_lock(struct percpu_rwlock *pcpu_rwlock)
> +void percpu_read_lock_irqsafe(struct percpu_rwlock *pcpu_rwlock)
> {
> preempt_disable();
>
> /* First and foremost, let the writer know that a reader is active */
> - this_cpu_inc(*pcpu_rwlock->reader_refcnt);
> + this_cpu_add(*pcpu_rwlock->reader_refcnt, READER_PRESENT);
>
> /*
> * If we are already using per-cpu refcounts, it is not safe to switch
> * the synchronization scheme. So continue using the refcounts.
> */
> if (reader_nested_percpu(pcpu_rwlock)) {
> - goto out;
> + this_cpu_inc(*pcpu_rwlock->reader_refcnt);
Hmmm... If the reader is nested, it -doesn't- need the memory barrier at
the end of this function. If there is lots of nesting, it might be
worth getting rid of it.
> } else {
> /*
> * The write to 'reader_refcnt' must be visible before we
> @@ -83,9 +83,19 @@ void percpu_read_lock(struct percpu_rwlock *pcpu_rwlock)
> smp_mb(); /* Paired with smp_rmb() in sync_reader() */
>
> if (likely(!writer_active(pcpu_rwlock))) {
> - goto out;
> + this_cpu_inc(*pcpu_rwlock->reader_refcnt);
> } else {
> /* Writer is active, so switch to global rwlock. */
> +
> + /*
> + * While we are spinning on ->global_rwlock, an
> + * interrupt can hit us, and the interrupt handler
> + * might call this function. The distinction between
> + * READER_PRESENT and the refcnt helps ensure that the
> + * interrupt handler also takes this branch and spins
> + * on the ->global_rwlock, as long as the writer is
> + * active.
> + */
> read_lock(&pcpu_rwlock->global_rwlock);
>
> /*
> @@ -95,26 +105,27 @@ void percpu_read_lock(struct percpu_rwlock *pcpu_rwlock)
> * back to per-cpu refcounts. (This also helps avoid
> * heterogeneous nesting of readers).
> */
> - if (writer_active(pcpu_rwlock))
> - this_cpu_dec(*pcpu_rwlock->reader_refcnt);
> - else
> + if (!writer_active(pcpu_rwlock)) {
> + this_cpu_inc(*pcpu_rwlock->reader_refcnt);
> read_unlock(&pcpu_rwlock->global_rwlock);
> + }
> }
> }
>
> -out:
> + this_cpu_sub(*pcpu_rwlock->reader_refcnt, READER_PRESENT);
> +
> /* Prevent reordering of any subsequent reads */
> smp_rmb();
> }
>
> -void percpu_read_unlock(struct percpu_rwlock *pcpu_rwlock)
> +void percpu_read_unlock_irqsafe(struct percpu_rwlock *pcpu_rwlock)
> {
> /*
> * We never allow heterogeneous nesting of readers. So it is trivial
> * to find out the kind of reader we are, and undo the operation
> * done by our corresponding percpu_read_lock().
> */
> - if (__this_cpu_read(*pcpu_rwlock->reader_refcnt)) {
> + if (reader_nested_percpu(pcpu_rwlock)) {
> this_cpu_dec(*pcpu_rwlock->reader_refcnt);
> smp_wmb(); /* Paired with smp_rmb() in sync_reader() */
> } else {
> @@ -184,7 +195,8 @@ static void sync_all_readers(struct percpu_rwlock *pcpu_rwlock)
> sync_reader(pcpu_rwlock, cpu);
> }
>
> -void percpu_write_lock(struct percpu_rwlock *pcpu_rwlock)
> +void percpu_write_lock_irqsave(struct percpu_rwlock *pcpu_rwlock,
> + unsigned long *flags)
> {
> /*
> * Tell all readers that a writer is becoming active, so that they
> @@ -192,10 +204,11 @@ void percpu_write_lock(struct percpu_rwlock *pcpu_rwlock)
> */
> announce_writer_active(pcpu_rwlock);
> sync_all_readers(pcpu_rwlock);
> - write_lock(&pcpu_rwlock->global_rwlock);
> + write_lock_irqsave(&pcpu_rwlock->global_rwlock, *flags);
> }
>
> -void percpu_write_unlock(struct percpu_rwlock *pcpu_rwlock)
> +void percpu_write_unlock_irqrestore(struct percpu_rwlock *pcpu_rwlock,
> + unsigned long *flags)
> {
> /*
> * Inform all readers that we are done, so that they can switch back
> @@ -203,6 +216,6 @@ void percpu_write_unlock(struct percpu_rwlock *pcpu_rwlock)
> * see it).
> */
> announce_writer_inactive(pcpu_rwlock);
> - write_unlock(&pcpu_rwlock->global_rwlock);
> + write_unlock_irqrestore(&pcpu_rwlock->global_rwlock, *flags);
> }
>
>
^ permalink raw reply
* Re: [PATCH v5 06/45] percpu_rwlock: Allow writers to be readers, and add lockdep annotations
From: Paul E. McKenney @ 2013-02-08 23:47 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: tglx, peterz, tj, oleg, rusty, mingo, akpm, namhyung, rostedt,
wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux, nikunj,
linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev, netdev,
linux-doc, linux-kernel
In-Reply-To: <20130122073416.13822.96504.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:04:23PM +0530, Srivatsa S. Bhat wrote:
> CPU hotplug (which will be the first user of per-CPU rwlocks) has a special
> requirement with respect to locking: the writer, after acquiring the per-CPU
> rwlock for write, must be allowed to take the same lock for read, without
> deadlocking and without getting complaints from lockdep. In comparison, this
> is similar to what get_online_cpus()/put_online_cpus() does today: it allows
> a hotplug writer (who holds the cpu_hotplug.lock mutex) to invoke it without
> locking issues, because it silently returns if the caller is the hotplug
> writer itself.
>
> This can be easily achieved with per-CPU rwlocks as well (even without a
> "is this a writer?" check) by incrementing the per-CPU refcount of the writer
> immediately after taking the global rwlock for write, and then decrementing
> the per-CPU refcount before releasing the global rwlock.
> This ensures that any reader that comes along on that CPU while the writer is
> active (on that same CPU), notices the non-zero value of the nested counter
> and assumes that it is a nested read-side critical section and proceeds by
> just incrementing the refcount. Thus we prevent the reader from taking the
> global rwlock for read, which prevents the writer from deadlocking itself.
>
> Add that support and teach lockdep about this special locking scheme so
> that it knows that this sort of usage is valid. Also add the required lockdep
> annotations to enable it to detect common locking problems with per-CPU
> rwlocks.
Very nice! The write-side interrupt disabling ensures that the task
stays on CPU, as required.
One request: Could we please have a comment explaining the reasons for
the writer incrementing and decrementing the reader reference count?
It looked really really strange to me until I came back and read the
commit log. ;-)
Thanx, Paul
> Cc: David Howells <dhowells@redhat.com>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> ---
>
> lib/percpu-rwlock.c | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/lib/percpu-rwlock.c b/lib/percpu-rwlock.c
> index a8d177a..054a50a 100644
> --- a/lib/percpu-rwlock.c
> +++ b/lib/percpu-rwlock.c
> @@ -84,6 +84,10 @@ void percpu_read_lock_irqsafe(struct percpu_rwlock *pcpu_rwlock)
>
> if (likely(!writer_active(pcpu_rwlock))) {
> this_cpu_inc(*pcpu_rwlock->reader_refcnt);
> +
> + /* Pretend that we take global_rwlock for lockdep */
> + rwlock_acquire_read(&pcpu_rwlock->global_rwlock.dep_map,
> + 0, 0, _RET_IP_);
> } else {
> /* Writer is active, so switch to global rwlock. */
>
> @@ -108,6 +112,12 @@ void percpu_read_lock_irqsafe(struct percpu_rwlock *pcpu_rwlock)
> if (!writer_active(pcpu_rwlock)) {
> this_cpu_inc(*pcpu_rwlock->reader_refcnt);
> read_unlock(&pcpu_rwlock->global_rwlock);
> +
> + /*
> + * Pretend that we take global_rwlock for lockdep
> + */
> + rwlock_acquire_read(&pcpu_rwlock->global_rwlock.dep_map,
> + 0, 0, _RET_IP_);
> }
> }
> }
> @@ -128,6 +138,14 @@ void percpu_read_unlock_irqsafe(struct percpu_rwlock *pcpu_rwlock)
> if (reader_nested_percpu(pcpu_rwlock)) {
> this_cpu_dec(*pcpu_rwlock->reader_refcnt);
> smp_wmb(); /* Paired with smp_rmb() in sync_reader() */
> +
> + /*
> + * If this is the last decrement, then it is time to pretend
> + * to lockdep that we are releasing the read lock.
> + */
> + if (!reader_nested_percpu(pcpu_rwlock))
> + rwlock_release(&pcpu_rwlock->global_rwlock.dep_map,
> + 1, _RET_IP_);
> } else {
> read_unlock(&pcpu_rwlock->global_rwlock);
> }
> @@ -205,11 +223,14 @@ void percpu_write_lock_irqsave(struct percpu_rwlock *pcpu_rwlock,
> announce_writer_active(pcpu_rwlock);
> sync_all_readers(pcpu_rwlock);
> write_lock_irqsave(&pcpu_rwlock->global_rwlock, *flags);
> + this_cpu_inc(*pcpu_rwlock->reader_refcnt);
> }
>
> void percpu_write_unlock_irqrestore(struct percpu_rwlock *pcpu_rwlock,
> unsigned long *flags)
> {
> + this_cpu_dec(*pcpu_rwlock->reader_refcnt);
> +
> /*
> * Inform all readers that we are done, so that they can switch back
> * to their per-cpu refcounts. (We don't need to wait for them to
>
^ permalink raw reply
* Re: [PATCH v5 07/45] CPU hotplug: Provide APIs to prevent CPU offline from atomic context
From: Paul E. McKenney @ 2013-02-08 23:50 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: tglx, peterz, tj, oleg, rusty, mingo, akpm, namhyung, rostedt,
wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux, nikunj,
linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev, netdev,
linux-doc, linux-kernel
In-Reply-To: <20130122073446.13822.39253.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:04:54PM +0530, Srivatsa S. Bhat wrote:
> There are places where preempt_disable() or local_irq_disable() are used
> to prevent any CPU from going offline during the critical section. Let us
> call them as "atomic hotplug readers" ("atomic" because they run in atomic,
> non-preemptible contexts).
>
> Today, preempt_disable() or its equivalent works because the hotplug writer
> uses stop_machine() to take CPUs offline. But once stop_machine() is gone
> from the CPU hotplug offline path, the readers won't be able to prevent
> CPUs from going offline using preempt_disable().
>
> So the intent here is to provide synchronization APIs for such atomic hotplug
> readers, to prevent (any) CPUs from going offline, without depending on
> stop_machine() at the writer-side. The new APIs will look something like
> this: get_online_cpus_atomic() and put_online_cpus_atomic()
>
> Some important design requirements and considerations:
> -----------------------------------------------------
>
> 1. Scalable synchronization at the reader-side, especially in the fast-path
>
> Any synchronization at the atomic hotplug readers side must be highly
> scalable - avoid global single-holder locks/counters etc. Because, these
> paths currently use the extremely fast preempt_disable(); our replacement
> to preempt_disable() should not become ridiculously costly and also should
> not serialize the readers among themselves needlessly.
>
> At a minimum, the new APIs must be extremely fast at the reader side
> atleast in the fast-path, when no CPU offline writers are active.
>
> 2. preempt_disable() was recursive. The replacement should also be recursive.
>
> 3. No (new) lock-ordering restrictions
>
> preempt_disable() was super-flexible. It didn't impose any ordering
> restrictions or rules for nesting. Our replacement should also be equally
> flexible and usable.
>
> 4. No deadlock possibilities
>
> Regular per-cpu locking is not the way to go if we want to have relaxed
> rules for lock-ordering. Because, we can end up in circular-locking
> dependencies as explained in https://lkml.org/lkml/2012/12/6/290
>
> So, avoid the usual per-cpu locking schemes (per-cpu locks/per-cpu atomic
> counters with spin-on-contention etc) as much as possible, to avoid
> numerous deadlock possibilities from creeping in.
>
>
> Implementation of the design:
> ----------------------------
>
> We use per-CPU reader-writer locks for synchronization because:
>
> a. They are quite fast and scalable in the fast-path (when no writers are
> active), since they use fast per-cpu counters in those paths.
>
> b. They are recursive at the reader side.
>
> c. They provide a good amount of safety against deadlocks; they don't
> spring new deadlock possibilities on us from out of nowhere. As a
> result, they have relaxed locking rules and are quite flexible, and
> thus are best suited for replacing usages of preempt_disable() or
> local_irq_disable() at the reader side.
>
> Together, these satisfy all the requirements mentioned above.
>
> I'm indebted to Michael Wang and Xiao Guangrong for their numerous thoughtful
> suggestions and ideas, which inspired and influenced many of the decisions in
> this as well as previous designs. Thanks a lot Michael and Xiao!
>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Mike Frysinger <vapier@gentoo.org>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: David Howells <dhowells@redhat.com>
> Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Paul Mundt <lethal@linux-sh.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: x86@kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: uclinux-dist-devel@blackfin.uclinux.org
> Cc: linux-ia64@vger.kernel.org
> Cc: linux-mips@linux-mips.org
> Cc: linux-am33-list@redhat.com
> Cc: linux-parisc@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-s390@vger.kernel.org
> Cc: linux-sh@vger.kernel.org
> Cc: sparclinux@vger.kernel.org
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
With the change suggested by Namhyung:
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> ---
>
> arch/arm/Kconfig | 1 +
> arch/blackfin/Kconfig | 1 +
> arch/ia64/Kconfig | 1 +
> arch/mips/Kconfig | 1 +
> arch/mn10300/Kconfig | 1 +
> arch/parisc/Kconfig | 1 +
> arch/powerpc/Kconfig | 1 +
> arch/s390/Kconfig | 1 +
> arch/sh/Kconfig | 1 +
> arch/sparc/Kconfig | 1 +
> arch/x86/Kconfig | 1 +
> include/linux/cpu.h | 4 +++
> kernel/cpu.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++---
> 13 files changed, 69 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 67874b8..cb6b94b 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1616,6 +1616,7 @@ config NR_CPUS
> config HOTPLUG_CPU
> bool "Support for hot-pluggable CPUs"
> depends on SMP && HOTPLUG
> + select PERCPU_RWLOCK
> help
> Say Y here to experiment with turning CPUs off and on. CPUs
> can be controlled through /sys/devices/system/cpu.
> diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
> index b6f3ad5..83d9882 100644
> --- a/arch/blackfin/Kconfig
> +++ b/arch/blackfin/Kconfig
> @@ -261,6 +261,7 @@ config NR_CPUS
> config HOTPLUG_CPU
> bool "Support for hot-pluggable CPUs"
> depends on SMP && HOTPLUG
> + select PERCPU_RWLOCK
> default y
>
> config BF_REV_MIN
> diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
> index 3279646..c246772 100644
> --- a/arch/ia64/Kconfig
> +++ b/arch/ia64/Kconfig
> @@ -378,6 +378,7 @@ config HOTPLUG_CPU
> bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
> depends on SMP && EXPERIMENTAL
> select HOTPLUG
> + select PERCPU_RWLOCK
> default n
> ---help---
> Say Y here to experiment with turning CPUs off and on. CPUs
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 2ac626a..f97c479 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -956,6 +956,7 @@ config SYS_HAS_EARLY_PRINTK
> config HOTPLUG_CPU
> bool "Support for hot-pluggable CPUs"
> depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU
> + select PERCPU_RWLOCK
> help
> Say Y here to allow turning CPUs off and on. CPUs can be
> controlled through /sys/devices/system/cpu.
> diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
> index e70001c..a64e488 100644
> --- a/arch/mn10300/Kconfig
> +++ b/arch/mn10300/Kconfig
> @@ -60,6 +60,7 @@ config ARCH_HAS_ILOG2_U32
>
> config HOTPLUG_CPU
> def_bool n
> + select PERCPU_RWLOCK
>
> source "init/Kconfig"
>
> diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
> index b77feff..6f55cd4 100644
> --- a/arch/parisc/Kconfig
> +++ b/arch/parisc/Kconfig
> @@ -226,6 +226,7 @@ config HOTPLUG_CPU
> bool
> default y if SMP
> select HOTPLUG
> + select PERCPU_RWLOCK
>
> config ARCH_SELECT_MEMORY_MODEL
> def_bool y
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 17903f1..56b1f15 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -336,6 +336,7 @@ config HOTPLUG_CPU
> bool "Support for enabling/disabling CPUs"
> depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || \
> PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
> + select PERCPU_RWLOCK
> ---help---
> Say Y here to be able to disable and re-enable individual
> CPUs at runtime on SMP machines.
> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> index b5ea38c..a9aafb4 100644
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -299,6 +299,7 @@ config HOTPLUG_CPU
> prompt "Support for hot-pluggable CPUs"
> depends on SMP
> select HOTPLUG
> + select PERCPU_RWLOCK
> help
> Say Y here to be able to turn CPUs off and on. CPUs
> can be controlled through /sys/devices/system/cpu/cpu#.
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index babc2b8..8c92eef 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -765,6 +765,7 @@ config NR_CPUS
> config HOTPLUG_CPU
> bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
> depends on SMP && HOTPLUG && EXPERIMENTAL
> + select PERCPU_RWLOCK
> help
> Say Y here to experiment with turning CPUs off and on. CPUs
> can be controlled through /sys/devices/system/cpu.
> diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
> index 9f2edb5..e2bd573 100644
> --- a/arch/sparc/Kconfig
> +++ b/arch/sparc/Kconfig
> @@ -253,6 +253,7 @@ config HOTPLUG_CPU
> bool "Support for hot-pluggable CPUs"
> depends on SPARC64 && SMP
> select HOTPLUG
> + select PERCPU_RWLOCK
> help
> Say Y here to experiment with turning CPUs off and on. CPUs
> can be controlled through /sys/devices/system/cpu/cpu#.
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 79795af..a225d12 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -1689,6 +1689,7 @@ config PHYSICAL_ALIGN
> config HOTPLUG_CPU
> bool "Support for hot-pluggable CPUs"
> depends on SMP && HOTPLUG
> + select PERCPU_RWLOCK
> ---help---
> Say Y here to allow turning CPUs off and on. CPUs can be
> controlled through /sys/devices/system/cpu.
> diff --git a/include/linux/cpu.h b/include/linux/cpu.h
> index ce7a074..cf24da1 100644
> --- a/include/linux/cpu.h
> +++ b/include/linux/cpu.h
> @@ -175,6 +175,8 @@ extern struct bus_type cpu_subsys;
>
> extern void get_online_cpus(void);
> extern void put_online_cpus(void);
> +extern void get_online_cpus_atomic(void);
> +extern void put_online_cpus_atomic(void);
> #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri)
> #define register_hotcpu_notifier(nb) register_cpu_notifier(nb)
> #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb)
> @@ -198,6 +200,8 @@ static inline void cpu_hotplug_driver_unlock(void)
>
> #define get_online_cpus() do { } while (0)
> #define put_online_cpus() do { } while (0)
> +#define get_online_cpus_atomic() do { } while (0)
> +#define put_online_cpus_atomic() do { } while (0)
> #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0)
> /* These aren't inline functions due to a GCC bug. */
> #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 3046a50..1c84138 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -1,6 +1,18 @@
> /* CPU control.
> * (C) 2001, 2002, 2003, 2004 Rusty Russell
> *
> + * Rework of the CPU hotplug offline mechanism to remove its dependence on
> + * the heavy-weight stop_machine() primitive, by Srivatsa S. Bhat and
> + * Paul E. McKenney.
> + *
> + * Copyright (C) IBM Corporation, 2012-2013
> + * Authors: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> + * Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> + *
> + * With lots of invaluable suggestions from:
> + * Oleg Nesterov <oleg@redhat.com>
> + * Tejun Heo <tj@kernel.org>
> + *
> * This code is licenced under the GPL.
> */
> #include <linux/proc_fs.h>
> @@ -19,6 +31,7 @@
> #include <linux/mutex.h>
> #include <linux/gfp.h>
> #include <linux/suspend.h>
> +#include <linux/percpu-rwlock.h>
>
> #include "smpboot.h"
>
> @@ -133,6 +146,38 @@ static void cpu_hotplug_done(void)
> mutex_unlock(&cpu_hotplug.lock);
> }
>
> +/*
> + * Per-CPU Reader-Writer lock to synchronize between atomic hotplug
> + * readers and the CPU offline hotplug writer.
> + */
> +DEFINE_STATIC_PERCPU_RWLOCK(hotplug_pcpu_rwlock);
> +
> +/*
> + * Invoked by atomic hotplug reader (a task which wants to prevent
> + * CPU offline, but which can't afford to sleep), to prevent CPUs from
> + * going offline. So, you can call this function from atomic contexts
> + * (including interrupt handlers).
> + *
> + * Note: This does NOT prevent CPUs from coming online! It only prevents
> + * CPUs from going offline.
> + *
> + * You can call this function recursively.
> + *
> + * Returns with preemption disabled (but interrupts remain as they are;
> + * they are not disabled).
> + */
> +void get_online_cpus_atomic(void)
> +{
> + percpu_read_lock_irqsafe(&hotplug_pcpu_rwlock);
> +}
> +EXPORT_SYMBOL_GPL(get_online_cpus_atomic);
> +
> +void put_online_cpus_atomic(void)
> +{
> + percpu_read_unlock_irqsafe(&hotplug_pcpu_rwlock);
> +}
> +EXPORT_SYMBOL_GPL(put_online_cpus_atomic);
> +
> #else /* #if CONFIG_HOTPLUG_CPU */
> static void cpu_hotplug_begin(void) {}
> static void cpu_hotplug_done(void) {}
> @@ -246,15 +291,21 @@ struct take_cpu_down_param {
> static int __ref take_cpu_down(void *_param)
> {
> struct take_cpu_down_param *param = _param;
> - int err;
> + unsigned long flags;
> + int err = 0;
> +
> + percpu_write_lock_irqsave(&hotplug_pcpu_rwlock, &flags);
>
> /* Ensure this CPU doesn't handle any more interrupts. */
> err = __cpu_disable();
> if (err < 0)
> - return err;
> + goto out;
>
> cpu_notify(CPU_DYING | param->mod, param->hcpu);
> - return 0;
> +
> +out:
> + percpu_write_unlock_irqrestore(&hotplug_pcpu_rwlock, &flags);
> + return err;
> }
>
> /* Requires cpu_add_remove_lock to be held */
>
^ permalink raw reply
* Re: [PATCH v5 08/45] CPU hotplug: Convert preprocessor macros to static inline functions
From: Paul E. McKenney @ 2013-02-08 23:51 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: tglx, peterz, tj, oleg, rusty, mingo, akpm, namhyung, rostedt,
wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux, nikunj,
linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev, netdev,
linux-doc, linux-kernel
In-Reply-To: <20130122073500.13822.11469.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:05:02PM +0530, Srivatsa S. Bhat wrote:
> On 12/05/2012 06:10 AM, Andrew Morton wrote:
> "static inline C functions would be preferred if possible. Feel free to
> fix up the wrong crufty surrounding code as well ;-)"
>
> Convert the macros in the CPU hotplug code to static inline C functions.
>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> ---
>
> include/linux/cpu.h | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/cpu.h b/include/linux/cpu.h
> index cf24da1..eb79f47 100644
> --- a/include/linux/cpu.h
> +++ b/include/linux/cpu.h
> @@ -198,10 +198,10 @@ static inline void cpu_hotplug_driver_unlock(void)
>
> #else /* CONFIG_HOTPLUG_CPU */
>
> -#define get_online_cpus() do { } while (0)
> -#define put_online_cpus() do { } while (0)
> -#define get_online_cpus_atomic() do { } while (0)
> -#define put_online_cpus_atomic() do { } while (0)
> +static inline void get_online_cpus(void) {}
> +static inline void put_online_cpus(void) {}
> +static inline void get_online_cpus_atomic(void) {}
> +static inline void put_online_cpus_atomic(void) {}
> #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0)
> /* These aren't inline functions due to a GCC bug. */
> #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
>
^ permalink raw reply
* Re: [PATCH v5 09/45] smp, cpu hotplug: Fix smp_call_function_*() to prevent CPU offline properly
From: Paul E. McKenney @ 2013-02-09 0:07 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: tglx, peterz, tj, oleg, rusty, mingo, akpm, namhyung, rostedt,
wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux, nikunj,
linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev, netdev,
linux-doc, linux-kernel
In-Reply-To: <20130122073508.13822.12784.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:05:10PM +0530, Srivatsa S. Bhat wrote:
> Once stop_machine() is gone from the CPU offline path, we won't be able to
> depend on preempt_disable() to prevent CPUs from going offline from under us.
>
> Use the get/put_online_cpus_atomic() APIs to prevent CPUs from going offline,
> while invoking from atomic context.
>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Would it make sense for get_online_cpus_atomic() to return the current
CPU number? Looks good otherwise.
Thanx, Paul
> ---
>
> kernel/smp.c | 40 ++++++++++++++++++++++++++--------------
> 1 file changed, 26 insertions(+), 14 deletions(-)
>
> diff --git a/kernel/smp.c b/kernel/smp.c
> index 29dd40a..f421bcc 100644
> --- a/kernel/smp.c
> +++ b/kernel/smp.c
> @@ -310,7 +310,8 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info,
> * prevent preemption and reschedule on another processor,
> * as well as CPU removal
> */
> - this_cpu = get_cpu();
> + get_online_cpus_atomic();
> + this_cpu = smp_processor_id();
>
> /*
> * Can deadlock when called with interrupts disabled.
> @@ -342,7 +343,7 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info,
> }
> }
>
> - put_cpu();
> + put_online_cpus_atomic();
>
> return err;
> }
> @@ -371,8 +372,10 @@ int smp_call_function_any(const struct cpumask *mask,
> const struct cpumask *nodemask;
> int ret;
>
> + get_online_cpus_atomic();
> /* Try for same CPU (cheapest) */
> - cpu = get_cpu();
> + cpu = smp_processor_id();
> +
> if (cpumask_test_cpu(cpu, mask))
> goto call;
>
> @@ -388,7 +391,7 @@ int smp_call_function_any(const struct cpumask *mask,
> cpu = cpumask_any_and(mask, cpu_online_mask);
> call:
> ret = smp_call_function_single(cpu, func, info, wait);
> - put_cpu();
> + put_online_cpus_atomic();
> return ret;
> }
> EXPORT_SYMBOL_GPL(smp_call_function_any);
> @@ -409,25 +412,28 @@ void __smp_call_function_single(int cpu, struct call_single_data *data,
> unsigned int this_cpu;
> unsigned long flags;
>
> - this_cpu = get_cpu();
> + get_online_cpus_atomic();
> +
> + this_cpu = smp_processor_id();
> +
> /*
> * Can deadlock when called with interrupts disabled.
> * We allow cpu's that are not yet online though, as no one else can
> * send smp call function interrupt to this cpu and as such deadlocks
> * can't happen.
> */
> - WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled()
> + WARN_ON_ONCE(cpu_online(this_cpu) && wait && irqs_disabled()
> && !oops_in_progress);
>
> if (cpu == this_cpu) {
> local_irq_save(flags);
> data->func(data->info);
> local_irq_restore(flags);
> - } else {
> + } else if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
> csd_lock(data);
> generic_exec_single(cpu, data, wait);
> }
> - put_cpu();
> + put_online_cpus_atomic();
> }
>
> /**
> @@ -451,6 +457,8 @@ void smp_call_function_many(const struct cpumask *mask,
> unsigned long flags;
> int refs, cpu, next_cpu, this_cpu = smp_processor_id();
>
> + get_online_cpus_atomic();
> +
> /*
> * Can deadlock when called with interrupts disabled.
> * We allow cpu's that are not yet online though, as no one else can
> @@ -467,17 +475,18 @@ void smp_call_function_many(const struct cpumask *mask,
>
> /* No online cpus? We're done. */
> if (cpu >= nr_cpu_ids)
> - return;
> + goto out_unlock;
>
> /* Do we have another CPU which isn't us? */
> next_cpu = cpumask_next_and(cpu, mask, cpu_online_mask);
> if (next_cpu == this_cpu)
> - next_cpu = cpumask_next_and(next_cpu, mask, cpu_online_mask);
> + next_cpu = cpumask_next_and(next_cpu, mask,
> + cpu_online_mask);
>
> /* Fastpath: do that cpu by itself. */
> if (next_cpu >= nr_cpu_ids) {
> smp_call_function_single(cpu, func, info, wait);
> - return;
> + goto out_unlock;
> }
>
> data = &__get_cpu_var(cfd_data);
> @@ -523,7 +532,7 @@ void smp_call_function_many(const struct cpumask *mask,
> /* Some callers race with other cpus changing the passed mask */
> if (unlikely(!refs)) {
> csd_unlock(&data->csd);
> - return;
> + goto out_unlock;
> }
>
> raw_spin_lock_irqsave(&call_function.lock, flags);
> @@ -554,6 +563,9 @@ void smp_call_function_many(const struct cpumask *mask,
> /* Optionally wait for the CPUs to complete */
> if (wait)
> csd_lock_wait(&data->csd);
> +
> +out_unlock:
> + put_online_cpus_atomic();
> }
> EXPORT_SYMBOL(smp_call_function_many);
>
> @@ -574,9 +586,9 @@ EXPORT_SYMBOL(smp_call_function_many);
> */
> int smp_call_function(smp_call_func_t func, void *info, int wait)
> {
> - preempt_disable();
> + get_online_cpus_atomic();
> smp_call_function_many(cpu_online_mask, func, info, wait);
> - preempt_enable();
> + put_online_cpus_atomic();
>
> return 0;
> }
>
^ permalink raw reply
* Re: [PATCH v5 14/45] rcu, CPU hotplug: Fix comment referring to stop_machine()
From: Paul E. McKenney @ 2013-02-09 0:14 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: linux-doc, peterz, fweisbec, linux-kernel, mingo, linux-arch,
linux, xiaoguangrong, wangyun, nikunj, linux-pm, rusty, rostedt,
rjw, namhyung, tglx, linux-arm-kernel, netdev, oleg, sbw, tj,
akpm, linuxppc-dev
In-Reply-To: <20130122073630.13822.99359.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:06:34PM +0530, Srivatsa S. Bhat wrote:
> Don't refer to stop_machine() in the CPU hotplug path, since we are going
> to get rid of it. Also, move the comment referring to callback adoption
> to the CPU_DEAD case, because that's where it happens now.
>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Ouch! That comment is indeed obsolete and must die.
I queued this to -rcu with your Signed-off-by. However, I omitted
the added comment, as it is imcomplete -- it is easy to look at
rcu_cleanup_dead_cpu() to see what it does.
Thanx, Paul
> ---
>
> kernel/rcutree.c | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index e441b77..ac94474 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -2827,11 +2827,6 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
> break;
> case CPU_DYING:
> case CPU_DYING_FROZEN:
> - /*
> - * The whole machine is "stopped" except this CPU, so we can
> - * touch any data without introducing corruption. We send the
> - * dying CPU's callbacks to an arbitrarily chosen online CPU.
> - */
> for_each_rcu_flavor(rsp)
> rcu_cleanup_dying_cpu(rsp);
> rcu_cleanup_after_idle(cpu);
> @@ -2840,6 +2835,10 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
> case CPU_DEAD_FROZEN:
> case CPU_UP_CANCELED:
> case CPU_UP_CANCELED_FROZEN:
> + /*
> + * We send the dead CPU's callbacks to an arbitrarily chosen
> + * online CPU.
> + */
> for_each_rcu_flavor(rsp)
> rcu_cleanup_dead_cpu(cpu, rsp);
> break;
>
^ permalink raw reply
* Re: [PATCH v5 44/45] CPU hotplug, stop_machine: Decouple CPU hotplug from stop_machine() in Kconfig
From: Paul E. McKenney @ 2013-02-09 0:15 UTC (permalink / raw)
To: Srivatsa S. Bhat
Cc: tglx, peterz, tj, oleg, rusty, mingo, akpm, namhyung, rostedt,
wangyun, xiaoguangrong, rjw, sbw, fweisbec, linux, nikunj,
linux-pm, linux-arch, linux-arm-kernel, linuxppc-dev, netdev,
linux-doc, linux-kernel
In-Reply-To: <20130122074518.13822.86992.stgit@srivatsabhat.in.ibm.com>
On Tue, Jan 22, 2013 at 01:15:22PM +0530, Srivatsa S. Bhat wrote:
> ... and also cleanup a comment that refers to CPU hotplug being dependent on
> stop_machine().
>
> Cc: David Howells <dhowells@redhat.com>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
(Hey, I thought I owed myself an easy one!)
> ---
>
> include/linux/stop_machine.h | 2 +-
> init/Kconfig | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h
> index 3b5e910..ce2d3c4 100644
> --- a/include/linux/stop_machine.h
> +++ b/include/linux/stop_machine.h
> @@ -120,7 +120,7 @@ int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus);
> * @cpus: the cpus to run the @fn() on (NULL = any online cpu)
> *
> * Description: This is a special version of the above, which assumes cpus
> - * won't come or go while it's being called. Used by hotplug cpu.
> + * won't come or go while it's being called.
> */
> int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus);
>
> diff --git a/init/Kconfig b/init/Kconfig
> index be8b7f5..048a0c5 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1711,7 +1711,7 @@ config INIT_ALL_POSSIBLE
> config STOP_MACHINE
> bool
> default y
> - depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU
> + depends on (SMP && MODULE_UNLOAD)
> help
> Need stop_machine() primitive.
>
>
^ 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