Always print the first 50 messages of each type. After that, optionally rate-limit the messages. This provides a way to limit the overhead of processing excessive messages without suppressing the first few of any type.
As part of this change, we are switching from direct printf() calls to collecting data in an sbuf(9). In POLLED mode (run from a task queue), we collect the message in the buffer and print it all at once after checkingwe dynamically allocate the rate limitbuffer. In the other modes (which are likely called from a hardware interrupt), we use a buffer allocated from the BSS segment and guarded by a lock. In normal operation, most calls to mca_log() should come from the POLLED mode, so there should be no contention for the new lock. we do not ratIf there is an interrupt storm which exceeds the capacity of the free limit.st, Instead,there will be new contention for this lock; we use a small buffer on the stack and drain to printf() as the buffer is filled.however, Because most calls to mca_log() should come from the POLLED modeoverall lock contention should still be lower than it was prior to e770e32aa3a0, the rate limit should be effective for most messageswhen the mca_lock was held for the entirety of the mca_log() call.
Note: This mechanism was first suggested by Loic Prylli and the code is a reworked version of his patch.
Note 2: My long-term idea for this code is to add additional output options besides printf(). I think the use of the sbuf helps lay the groundwork for thatThis commit is partly based on a patch proposed by Loic Prylli <lprylli@netflix.com>.