Re: [PATCH net-next v5] rtnetlink: Support fine-grained netdevice bulk deletion
flat view
From: Lahav Schlesinger <hidden>
Date: 2022-01-04 08:21:34
On Wed, Dec 08, 2021 at 04:45:44PM -0800, Jakub Kicinski wrote:
CAUTION: External E-Mail - Use caution with links and attachments On Wed, 8 Dec 2021 17:18:48 -0700 David Ahern wrote:quoted
On 12/8/21 5:04 PM, Jakub Kicinski wrote:quoted
quoted
I think marking the dev's and then using a delete loop is going to be the better approach - avoid the sort and duplicate problem. I use that approach for nexthop deletes: https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_netdev_net-2Dnext.git_tree_net_ipv4_nexthop.c-23n1849&d=DwICAg&c=euGZstcaTDllvimEN8b7jXrwqOf-v5A_CdpgnVfiiMM&r=-WbGKi6-8WU3IfnrkySymtcZWJMn_aVdolIPebPZGu4&m=td9sv1_NnALM3QjLFg8h9u1P7DUJJL2YhzqyneZ95Gc&s=nEGgvxCwd3MrSXWhv-5Fo7mUlBkuKbHRBAO4VO9mG2o&e= Find a hole in net_device struct in an area used only for control path and add 'bool grp_delete' (or a 1-bit hole). Mark the devices on pass and delete them on another.If we want to keep state in the netdev itself we can probably piggy back on dev->unreg_list. It should be initialized to empty and not touched unless device goes thru unregister.isn't that used when the delink function calls unregister_netdevice_queue?Sure but all the validation is before we start calling delink, so doesn't matter? list to_kill, queued; for_each_attr(nest) { ... dev = get_by_index(nla_get_s32(..)); if (!dev) goto cleanup; if (!list_empty(&dev->unreg_list)) goto cleanup; ... list_add(&to_kill, &dev->unreg_list); } for_each_entry_safe(to_kill) { list_del_init(&dev->unreg_list); ->dellink(dev, queued); } unreg_many(queued); return cleanup: for_each_entry_safe(to_kill) { list_del_init(&dev->unreg_list); } No?
Hi Jakub, I just sent a V6 for this patch. Just wanted to note that I tried this approach of using unreg_list, but it caused issues with e.g. veth deletion - the dellink() of a veth peer automatically adds the other peer to the queued list. So if the list of ifindices contains both peers then when 'to_kill' is iterated, both the current device and the next pointer will have their 'unreg_list' moved to the other list, which later raised a page fault when 'to_kill' was further iterated upon. Therefore instead I added a big flag in a "hole" inside struct net_device, as David suggested.