In the Linux kernel, the following vulnerability has been resolved:
ibmvnic: Do not reset dql stats on NON_FATAL err
All ibmvnic resets, make a call to netdevtxresetqueue() when re-opening the device. netdevtxresetqueue() resets the numqueued and numcompleted byte counters. These stats are used in Byte Queue Limit (BQL) algorithms. The difference between these two stats tracks the number of bytes currently sitting on the physical NIC. ibmvnic increases the number of queued bytes though calls to netdevtxsentqueue() in the drivers xmit function. When, VIOS reports that it is done transmitting bytes, the ibmvnic device increases the number of completed bytes through calls to netdevtxcompletedqueue(). It is important to note that the driver batches its transmit calls and num_queued is increased every time that an skb is added to the next batch, not necessarily when the batch is sent to VIOS for transmission.
Unlike other reset types, a NON FATAL reset will not flush the sub crq tx buffers. Therefore, it is possible for the batched skb array to be partially full. So if there is call to netdevtxresetqueue() when re-opening the device, the value of numqueued (0) would not account for the skb's that are currently batched. Eventually, when the batch is sent to VIOS, the call to netdevtxcompletedqueue() would increase numcompleted to a value greater than the numqueued. This causes a BUGON crash:
ibmvnic 30000002: Firmware reports error, cause: adapter problem. Starting recovery... ibmvnic 30000002: tx error 600 ibmvnic 30000002: tx error 600 ibmvnic 30000002: tx error 600 ibmvnic 30000002: tx error 600 ------------[ cut here ]------------ kernel BUG at lib/dynamicqueuelimits.c:27! Oops: Exception in kernel mode, sig: 5 [....] NIP dqlcompleted+0x28/0x1c0 LR ibmvniccompletetx.isra.0+0x23c/0x420 [ibmvnic] Call Trace: ibmvniccompletetx.isra.0+0x3f8/0x420 [ibmvnic] (unreliable) ibmvnicinterrupttx+0x40/0x70 [ibmvnic] _handleirqevent_percpu+0x98/0x270 ---[ end trace ]---
Therefore, do not reset the dql stats when performing a NON_FATAL reset.