diff mbox

[net-next] net: remove some useless list_del()

Message ID 1401840715-16375-2-git-send-email-xiyou.wangcong@gmail.com
State Rejected, archived
Delegated to: David Miller
Headers show

Commit Message

Cong Wang June 4, 2014, 12:11 a.m. UTC
"list_kill" is allocated on stack and it's a list head,
it is pointless to call list_del(&kill_list) especially
after unregister_netdevice_many().

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 drivers/net/macvlan.c | 1 -
 net/core/rtnetlink.c  | 1 -
 2 files changed, 2 deletions(-)

Comments

David Miller June 4, 2014, 12:24 a.m. UTC | #1
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Tue,  3 Jun 2014 17:11:55 -0700

> "list_kill" is allocated on stack and it's a list head,
> it is pointless to call list_del(&kill_list) especially
> after unregister_netdevice_many().
> 
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>

Do not edit what you do not understand:

commit ceaaec98ad99859ac90ac6863ad0a6cd075d8e0e                                                                         
Author: Eric Dumazet <eric.dumazet@gmail.com>                                                                           
Date:   Thu Feb 17 22:59:19 2011 +0000                                                                                  
                                                                                                                        
    net: deinit automatic LIST_HEAD                                                                                     
                                                                                                                        
    commit 9b5e383c11b08784 (net: Introduce                                                                             
    unregister_netdevice_many()) left an active LIST_HEAD() in                                                          
    rollback_registered(), with possible memory corruption.                                                             
                                                                                                                        
    Even if device is freed without touching its unreg_list (and therefore                                              
    touching the previous memory location holding LISTE_HEAD(single), better                                            
    close the bug for good, since its really subtle.                                                                    
                                                                                                                        
    (Same fix for default_device_exit_batch() for completeness)                                                         
                                                                                                                        
    Reported-by: Michal Hocko <mhocko@suse.cz>                                                                          
    Tested-by: Michal Hocko <mhocko@suse.cz>                                                                            
    Reported-by: Eric W. Biderman <ebiderman@xmission.com>                                                              
    Tested-by: Eric W. Biderman <ebiderman@xmission.com>                                                                
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>                                                       
    Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>                                                                
    CC: Ingo Molnar <mingo@elte.hu>                                                                                     
    CC: Octavian Purdila <opurdila@ixiacom.com>                                                                         
    CC: stable <stable@kernel.org> [.33+]                                                                               
    Signed-off-by: David S. Miller <davem@davemloft.net>                                                                
--
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
Eric Dumazet June 4, 2014, 12:43 a.m. UTC | #2
On Tue, 2014-06-03 at 17:11 -0700, Cong Wang wrote:
> "list_kill" is allocated on stack and it's a list head,
> it is pointless to call list_del(&kill_list) especially
> after unregister_netdevice_many().

How pointless exactly ? Explain more please.

I suggest you read various commits adding these list_del()

f87e6f47933e3ebeced9bb12615e830a72cedce4 is a good start.



--
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
Alexei Starovoitov June 4, 2014, 2:18 a.m. UTC | #3
On Tue, Jun 3, 2014 at 5:43 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Tue, 2014-06-03 at 17:11 -0700, Cong Wang wrote:
>> "list_kill" is allocated on stack and it's a list head,
>> it is pointless to call list_del(&kill_list) especially
>> after unregister_netdevice_many().
>
> How pointless exactly ? Explain more please.
>
> I suggest you read various commits adding these list_del()
>
> f87e6f47933e3ebeced9bb12615e830a72cedce4 is a good start.

Interesting thread. Thanks guys!
detailed explanation by Linus:
https://lkml.org/lkml/2011/2/17/267
--
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
Daniel Borkmann June 4, 2014, 8:26 a.m. UTC | #4
On 06/04/2014 04:18 AM, Alexei Starovoitov wrote:
> On Tue, Jun 3, 2014 at 5:43 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> On Tue, 2014-06-03 at 17:11 -0700, Cong Wang wrote:
>>> "list_kill" is allocated on stack and it's a list head,
>>> it is pointless to call list_del(&kill_list) especially
>>> after unregister_netdevice_many().
>>
>> How pointless exactly ? Explain more please.
>>
>> I suggest you read various commits adding these list_del()
>>
>> f87e6f47933e3ebeced9bb12615e830a72cedce4 is a good start.
>
> Interesting thread. Thanks guys!
> detailed explanation by Linus:
> https://lkml.org/lkml/2011/2/17/267

Indeed, thanks for the pointer. On that note, if you grep for
unregister_netdevice_many() invocations, you'll see many more
such cases that would need a list_del() actually.
--
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
Cong Wang June 6, 2014, 6:40 a.m. UTC | #5
On Tue, Jun 3, 2014 at 5:43 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Tue, 2014-06-03 at 17:11 -0700, Cong Wang wrote:
>> "list_kill" is allocated on stack and it's a list head,
>> it is pointless to call list_del(&kill_list) especially
>> after unregister_netdevice_many().
>
> How pointless exactly ? Explain more please.
>
> I suggest you read various commits adding these list_del()
>
> f87e6f47933e3ebeced9bb12615e830a72cedce4 is a good start.
>

If after unregister_netdevice_many() dev->unreg_list is still needed,
then it's a nightmare to maintain these list_head's in dev:

struct list_head dev_list;
struct list_head napi_list;
struct list_head unreg_list;
struct list_head close_list;

struct list_head todo_list;

Same for struct net.
--
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
Eric Dumazet June 6, 2014, 1:17 p.m. UTC | #6
On Thu, 2014-06-05 at 23:40 -0700, Cong Wang wrote:
> On Tue, Jun 3, 2014 at 5:43 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > On Tue, 2014-06-03 at 17:11 -0700, Cong Wang wrote:
> >> "list_kill" is allocated on stack and it's a list head,
> >> it is pointless to call list_del(&kill_list) especially
> >> after unregister_netdevice_many().
> >
> > How pointless exactly ? Explain more please.
> >
> > I suggest you read various commits adding these list_del()
> >
> > f87e6f47933e3ebeced9bb12615e830a72cedce4 is a good start.
> >
> 
> If after unregister_netdevice_many() dev->unreg_list is still needed,
> then it's a nightmare to maintain these list_head's in dev:
> 
> struct list_head dev_list;
> struct list_head napi_list;
> struct list_head unreg_list;
> struct list_head close_list;
> 
> struct list_head todo_list;
> 
> Same for struct net.


You did not really understood the problem.

This has _nothing_ to do with dev->unreg_list

Really this is all explained in the commit I gave.

In fact I suspect following is even needed :

Force the list_del() in unregister_netdevice_many(), because is really
too confusing and a common source of bugs.

I'll send a patch.


--
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
Cong Wang June 9, 2014, 5:58 a.m. UTC | #7
On Fri, Jun 6, 2014 at 6:17 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> You did not really understood the problem.
>
> This has _nothing_ to do with dev->unreg_list
>
> Really this is all explained in the commit I gave.


I did understand it, even before sending my patch.

I just don't even like this piece of sh*t, really, we have
to rewrite it, even after you move the list_del() into the callee.
It is still as ugly as it was.
--
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 mbox

Patch

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index eee9106..cd80245 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1204,7 +1204,6 @@  static int macvlan_device_event(struct notifier_block *unused,
 		list_for_each_entry_safe(vlan, next, &port->vlans, list)
 			vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
 		unregister_netdevice_many(&list_kill);
-		list_del(&list_kill);
 		break;
 	case NETDEV_PRE_TYPE_CHANGE:
 		/* Forbid underlaying device to change its type. */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f31268d..4a1cff6 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1770,7 +1770,6 @@  static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
 
 	ops->dellink(dev, &list_kill);
 	unregister_netdevice_many(&list_kill);
-	list_del(&list_kill);
 	return 0;
 }