From patchwork Wed Oct 23 05:34:35 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexei Starovoitov X-Patchwork-Id: 285521 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 16CD72C012E for ; Wed, 23 Oct 2013 16:34:54 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751025Ab3JWFeh (ORCPT ); Wed, 23 Oct 2013 01:34:37 -0400 Received: from mail-qc0-f173.google.com ([209.85.216.173]:55317 "EHLO mail-qc0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750846Ab3JWFeg (ORCPT ); Wed, 23 Oct 2013 01:34:36 -0400 Received: by mail-qc0-f173.google.com with SMTP id l13so185383qcy.4 for ; Tue, 22 Oct 2013 22:34:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=GeDV1/EQ4sMTMrMvPH58C77hcJc+sDgxs0gAY9eRoMk=; b=cEGmUjpXNXP3T7t8XC16KMG008Gfm5uqo325Z+t4veVUGzHb9e0+ceAvEwIqw+J37s pZF+fffSh7GRLKBFpnXkKJ7a47gKdTkvYAa9bfHU92kWAgtqEu/lCnhsHZr0HbjDx8/a RU67NBAmWqY2owtW56ylu+O+pdYZl0G8Ou5FO/9SoQ4+od0I1q/AmtOTcIz+2+VhPXFo kw1WtphsMQOm0WXZerFV/DL36bSp50Jlc5IxvahtOm0QN96Ce4ogcI+0kwzH91zNhAPD tkyze5jKj7uMxfgPrRESO1BvU/hmBWFxgO4G/kLu9kLnC4BBSRXZUdifPFWBBB4PkUwD Hh4A== MIME-Version: 1.0 X-Received: by 10.49.97.6 with SMTP id dw6mr34867081qeb.47.1382506475269; Tue, 22 Oct 2013 22:34:35 -0700 (PDT) Received: by 10.96.62.229 with HTTP; Tue, 22 Oct 2013 22:34:35 -0700 (PDT) In-Reply-To: References: Date: Tue, 22 Oct 2013 22:34:35 -0700 Message-ID: Subject: Re: BUG: scheduling while atomic dev_set_promiscuity->__dev_notify_flags From: Alexei Starovoitov To: Cong Wang Cc: netdev@vger.kernel.org, nicolas.dichtel@6wind.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On Tue, Oct 22, 2013 at 8:53 PM, Cong Wang wrote: > On Tue, 22 Oct 2013 at 01:04 GMT, Alexei Starovoitov wrote: >> >> packet_notifier() does rcu_read_lock() before calling into packet_dev_mc() . >> >> Not sure how to fix it cleanly, other than disabling a notify here. >> Any suggestion? >> > > Passing a gfp flag to rtmsg_ifinfo() seems a right fix for me, but I don't > know if there is other better way to fix it. Indeed. rtnl_notify() already accepts gfp_t. The following diff fixes it for me: --- include/linux/rtnetlink.h | 3 ++- net/core/dev.c | 2 +- net/core/rtnetlink.c | 12 +++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) @@ -2002,12 +2003,17 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change) kfree_skb(skb); goto errout; } - rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); + rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags); return; errout: if (err < 0) rtnl_set_sk_err(net, RTNLGRP_LINK, err); } + +void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change) +{ + __rtmsg_ifinfo(type, dev, change, GFP_KERNEL); +} EXPORT_SYMBOL(rtmsg_ifinfo); static int nlmsg_populate_fdb_fill(struct sk_buff *skb, -- Nicolas, I've sent you my .config. Any better ideas? Thanks Alex -- 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 diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index f28544b..0180523 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -15,7 +15,8 @@ extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics); extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, long expires, u32 error); -extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change); +void __rtmsg_ifinfo(int type, struct net_device *dev, unsigned change, gfp_t flags); +void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change); /* RTNL is used as a global lock for all changes to network configuration */ extern void rtnl_lock(void); diff --git a/net/core/dev.c b/net/core/dev.c index 0918aad..59b90fe 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5257,7 +5257,7 @@ void __dev_notify_flags(struct net_device *dev, unsigned int old_flags, unsigned int changes = dev->flags ^ old_flags; if (gchanges) - rtmsg_ifinfo(RTM_NEWLINK, dev, gchanges); + __rtmsg_ifinfo(RTM_NEWLINK, dev, gchanges, GFP_ATOMIC); if (changes & IFF_UP) { if (dev->flags & IFF_UP) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 4aedf03..5931af9 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1984,14 +1984,15 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } -void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change) +void __rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, + gfp_t flags) { struct net *net = dev_net(dev); struct sk_buff *skb; int err = -ENOBUFS; size_t if_info_size; - skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL); + skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags); if (skb == NULL) goto errout;