diff --git a/mm/iob/Kconfig b/mm/iob/Kconfig index bd5875b961..d39c6c4dad 100644 --- a/mm/iob/Kconfig +++ b/mm/iob/Kconfig @@ -71,6 +71,20 @@ config IOB_NOTIFIER support poll() logic where the poll must wait for an IOB to become available. +config IOB_NOTIFIER_DIV + int "Notification divider" + default 4 + range 1 64 + depends on IOB_NOTIFIER + ---help--- + IOBs may become available at very high rates and the resulting + notification processing can be substantial even if there is nothing + waiting for a free IOB. This divider will reduce that rate of + notification. This must be an even power of two. Supported values + include: 1, 2, 4, 8, 16, 32, 64. The default value of 4 means that + a notification will be sent only when there are a multiple of 4 IOBs + available. + config IOB_DEBUG bool "Force I/O buffer debug" default n diff --git a/mm/iob/iob_free.c b/mm/iob/iob_free.c index b29dafe610..980f43df4a 100644 --- a/mm/iob/iob_free.c +++ b/mm/iob/iob_free.c @@ -50,6 +50,28 @@ #include "iob.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if !defined(CONFIG_IOB_NOTIFIER_DIV) || CONFIG_IOB_NOTIFIER_DIV < 2 +# define IOB_DIVIDER 1 +#elif CONFIG_IOB_NOTIFIER_DIV < 4 +# define IOB_DIVIDER 2 +#elif CONFIG_IOB_NOTIFIER_DIV < 8 +# define IOB_DIVIDER 4 +#elif CONFIG_IOB_NOTIFIER_DIV < 16 +# define IOB_DIVIDER 8 +#elif CONFIG_IOB_NOTIFIER_DIV < 32 +# define IOB_DIVIDER 16 +#elif CONFIG_IOB_NOTIFIER_DIV < 64 +# define IOB_DIVIDER 32 +#else +# define IOB_DIVIDER 64 +#endif + +#define IOB_MASK (IOB_DIVIDER - 1) + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -67,6 +89,9 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob) { FAR struct iob_s *next = iob->io_flink; irqstate_t flags; +#ifdef CONFIG_IOB_NOTIFIER + int16_t navail; +#endif iobinfo("iob=%p io_pktlen=%u io_len=%u next=%p\n", iob, iob->io_pktlen, iob->io_len, next); @@ -149,7 +174,8 @@ FAR struct iob_s *iob_free(FAR struct iob_s *iob) * for an IOB. */ - if (iob_navail(false) > 0) + navail = iob_navail(false); + if (navail > 0 && (navail & IOB_MASK) == 0) { /* Signal any threads that have requested a signal notification * when an IOB becomes available.