That's what happens on rmmod with the four interfaces:
[ 70.772525] batman_adv: bat0: Removing interface: eth1
[ 70.778656] λλλ orig_node_del_if: del_if_num: 0, chunk_size: 8, max_if_num: 3, +dst: 0, +src: 8, num: 24
[ 71.101053] λλλ orig_node_del_if: del_if_num: 0, chunk_size: 8, max_if_num: 3, +dst: 0, +src: 8, num: 24
[ 71.422060] λλλ orig_node_del_if: del_if_num: 0, chunk_size: 8, max_if_num: 3, +dst: 0, +src: 8, num: 24
[ 71.701043] batman_adv: bat0: Interface deactivated: eth2
[ 71.703874] batman_adv: bat0: Removing interface: eth2
[ 71.707313] λλλ orig_node_del_if: del_if_num: 1, chunk_size: 8, max_if_num: 2, +dst: 8, +src: 16, num: 8
[ 72.001061] λλλ orig_node_del_if: del_if_num: 1, chunk_size: 8, max_if_num: 2, +dst: 8, +src: 16, num: 8
[ 72.318055] λλλ orig_node_del_if: del_if_num: 1, chunk_size: 8, max_if_num: 2, +dst: 8, +src: 16, num: 8
[ 72.643099] batman_adv: bat0: Interface deactivated: eth3
[ 72.645943] batman_adv: bat0: Removing interface: eth3
[ 72.696057] λλλ orig_node_del_if: del_if_num: 2, chunk_size: 8, max_if_num: 1, +dst: 16, +src: 24, num: -8
[ 72.849028] BUG: unable to handle kernel
- +dst: memcpy's dest offset (del_if_num * chunk_size)
- +src: memcpy's src offset ((del_if_num + 1) * chunk_size)
- num: number of bytes to copy (max_if_num - del_if_num) * chunk_size)
of this memcpy
When an interface is deleted, all following interfaces' if_num should be decreased by one, and not only the buffers should be resized. So after for instance "batman_adv: bat0: Removing interface: eth2", the del_if_num should still be 0, and not 1.
The tricky part is to reduce the "if_num"s by one and doing the resizing in one atomic operation... Looks like we need to introduce a spinlock for that?
Furthermore: Check, if there's a cast missing here:
Instead of:
orig_node->bcast_own + ((del_if_num + 1) * chunk_size),
do
(char*)orig_node->bcast_own + ((del_if_num + 1) * chunk_size),
or
orig_node->bcast_own + ((del_if_num + 1) * NUM_WORDS),