Hi Jozsef, On Mon, 9 Jul 2018 22:36:51 +0200 (CEST) Jozsef Kadlecsik <kadlec@xxxxxxxxxxxxxxxxx> wrote: > I believe the only modifications which are required are up till this point > in ip_set_list_set.c: ip_set_put_byindex(), moved outside of the > call_rcu() call. However, the ip_set_put_byindex() calls should be placed > after list_del_rcu() and list_replace_rcu(). This was also the first approach I took. With the changes you suggested, I guess this should look like the diff at [1]. Is this what you meant? However, list, flush and destroy are not serialised, so, with that patch, I do actually hit the BUG_ON(set->ref == 0) in ip_set_name_byindex(). That's why I think I can't rely on set->ref anymore with those changes: # while true; do ipset create h hash:ip; ipset create l list:set; ipset add l h; ipset flush; ipset destroy; done & # while true; do ipset list >/dev/null; done [wait a few minutes] [ 743.473640] ------------[ cut here ]------------ [ 743.477645] kernel BUG at net/netfilter/ipset/ip_set_core.c:707! [ 743.478954] invalid opcode: 0000 [#1] SMP NOPTI [ 743.479919] CPU: 1 PID: 22243 Comm: ipset Not tainted 4.18.0-rc3+ #94 [ 743.481273] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 [ 743.482677] RIP: 0010:ip_set_name_byindex+0x30/0x40 [ip_set] [ 743.483456] Code: 15 7d 69 00 00 48 8b 87 d0 13 00 00 0f b7 f6 48 8b 04 d0 48 8b 00 48 8b 04 f0 48 85 c0 74 09 8b 50 24 85 d2 74 04 f3 c3 0f 0b <0f> 0b 0f 1f 40 00 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 53 [ 743.486075] RSP: 0018:ffffb5acc2f03b50 EFLAGS: 00010246 [ 743.486799] RAX: ffff92fbaf93e900 RBX: ffff92fbba1edf00 RCX: 0000000000000000 [ 743.487748] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffffa85daf80 [ 743.488691] RBP: ffff92fb8bf11b00 R08: 0000000000000004 R09: ffff92fbafa18f30 [ 743.489649] R10: 0000000000000607 R11: ffff92fbaa86f000 R12: ffff92fbafa18f2c [ 743.490591] R13: ffff92fbaf93e240 R14: ffff92fbad8e9a80 R15: 0000000000000000 [ 743.491535] FS: 00007f3d6a460740(0000) GS:ffff92fbbfc80000(0000) knlGS:0000000000000000 [ 743.492601] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 743.493378] CR2: 00007ffd9e70b0a8 CR3: 0000000107322000 CR4: 00000000000006e0 [ 743.494339] Call Trace: [ 743.494677] list_set_list+0xfe/0x242 [ip_set_list_set] [ 743.495370] ip_set_dump_start+0x54c/0x6c0 [ip_set] [ 743.496017] ? __kmalloc_reserve.isra.46+0x2e/0x80 [ 743.496649] ? __alloc_skb+0x96/0x1e0 [ 743.497152] netlink_dump+0x106/0x2b0 [ 743.497640] netlink_recvmsg+0x332/0x430 [ 743.498163] ___sys_recvmsg+0xf5/0x240 [ 743.498662] ? netlink_sendmsg+0x120/0x3a0 [ 743.499212] ? __sys_sendto+0x10e/0x140 [ 743.499720] ? __sys_recvmsg+0x5b/0xa0 [ 743.500224] __sys_recvmsg+0x5b/0xa0 [ 743.500704] do_syscall_64+0x5b/0x180 [ 743.501210] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 743.501876] RIP: 0033:0x7f3d69b52df0 [ 743.502350] Code: 48 3d 01 f0 ff ff 73 01 c3 48 8b 0d 9a 70 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 83 3d ad d1 2c 00 00 75 10 b8 2f 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 be cd 00 00 48 89 04 24 [ 743.504825] RSP: 002b:00007ffd9e64b888 EFLAGS: 00000246 ORIG_RAX: 000000000000002f [ 743.505825] RAX: ffffffffffffffda RBX: ffffffffffffffff RCX: 00007f3d69b52df0 [ 743.506769] RDX: 0000000000000000 RSI: 00007ffd9e64b8b0 RDI: 0000000000000003 [ 743.507709] RBP: 0000000001aff4b8 R08: 00007f3d69851080 R09: 000000000000000c [ 743.508648] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000001000 [ 743.509601] R13: 0000000001b004c0 R14: 0000000000000000 R15: 0000000000000037 [ 743.510544] Modules linked in: ip_set_list_set ip_set_hash_ip ip_set nfnetlink sunrpc qxl ttm drm_kms_helper snd_hda_codec_generic syscopyarea sysfillrect snd_hda_intel sysimgblt fb_sys_fops snd_hda_codec drm edac_mce_amd snd_hda_core snd_hwdep joydev snd_pcm snd_timer snd soundcore pcspkr virtio_balloon i2c_piix4 ip_tables xfs libcrc32c ata_generic pata_acpi virtio_net net_failover virtio_blk failover virtio_console ata_piix serio_raw libata virtio_pci floppy virtio_ring virtio [ 743.516760] ---[ end trace ae334fe5735f7b30 ]--- [ 743.518014] RIP: 0010:ip_set_name_byindex+0x30/0x40 [ip_set] [ 743.519397] Code: 15 7d 69 00 00 48 8b 87 d0 13 00 00 0f b7 f6 48 8b 04 d0 48 8b 00 48 8b 04 f0 48 85 c0 74 09 8b 50 24 85 d2 74 04 f3 c3 0f 0b <0f> 0b 0f 1f 40 00 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 53 [ 743.523177] RSP: 0018:ffffb5acc2f03b50 EFLAGS: 00010246 [ 743.524519] RAX: ffff92fbaf93e900 RBX: ffff92fbba1edf00 RCX: 0000000000000000 [ 743.526114] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffffa85daf80 [ 743.527701] RBP: ffff92fb8bf11b00 R08: 0000000000000004 R09: ffff92fbafa18f30 [ 743.529292] R10: 0000000000000607 R11: ffff92fbaa86f000 R12: ffff92fbafa18f2c [ 743.530867] R13: ffff92fbaf93e240 R14: ffff92fbad8e9a80 R15: 0000000000000000 [ 743.532438] FS: 00007f3d6a460740(0000) GS:ffff92fbbfc80000(0000) knlGS:0000000000000000 [ 743.534141] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 743.535512] CR2: 00007ffd9e70b0a8 CR3: 0000000107322000 CR4: 00000000000006e0 [ 743.537097] Kernel panic - not syncing: Fatal exception Message from syslogd@localhost at Jul 9 17:26:29 ... kernel:Kernel panic - not syncing: Fatal exception [ 743.545671] Kernel Offset: 0x26400000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 743.547672] ---[ end Kernel panic - not syncing: Fatal exception ]--- [1] diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 072a658fde04..9a2392695d34 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c @@ -148,9 +148,7 @@ __list_set_del_rcu(struct rcu_head * rcu) { struct set_elem *e = container_of(rcu, struct set_elem, rcu); struct ip_set *set = e->set; - struct list_set *map = set->data; - ip_set_put_byindex(map->net, e->id); ip_set_ext_destroy(set, e); kfree(e); } @@ -158,15 +156,21 @@ __list_set_del_rcu(struct rcu_head * rcu) static inline void list_set_del(struct ip_set *set, struct set_elem *e) { + struct list_set *map = set->data; + set->elements--; list_del_rcu(&e->list); + ip_set_put_byindex(map->net, e->id); call_rcu(&e->rcu, __list_set_del_rcu); } static inline void -list_set_replace(struct set_elem *e, struct set_elem *old) +list_set_replace(struct ip_set *set, struct set_elem *e, struct set_elem *old) { + struct list_set *map = set->data; + list_replace_rcu(&old->list, &e->list); + ip_set_put_byindex(map->net, old->id); call_rcu(&old->rcu, __list_set_del_rcu); } @@ -298,7 +302,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext, INIT_LIST_HEAD(&e->list); list_set_init_extensions(set, ext, e); if (n) - list_set_replace(e, n); + list_set_replace(set, e, n); else if (next) list_add_tail_rcu(&e->list, &next->list); else if (prev) -- Stefano -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html