lsquic_spi.c revision 03fb9352
1229fce07SDmitri Tikhonov/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov/* 350aadb33SDmitri Tikhonov * lsquic_spi.c - implementation of Stream Priority Iterator. 450aadb33SDmitri Tikhonov */ 550aadb33SDmitri Tikhonov 650aadb33SDmitri Tikhonov#include <assert.h> 750aadb33SDmitri Tikhonov#include <inttypes.h> 850aadb33SDmitri Tikhonov#include <stdint.h> 950aadb33SDmitri Tikhonov#include <stdlib.h> 10c51ce338SDmitri Tikhonov#include <string.h> 1150aadb33SDmitri Tikhonov#include <sys/queue.h> 1250aadb33SDmitri Tikhonov#include <sys/types.h> 13461e84d8SAmol Deshpande#ifdef WIN32 14461e84d8SAmol Deshpande#include <vc_compat.h> 15461e84d8SAmol Deshpande#endif 1650aadb33SDmitri Tikhonov 1750aadb33SDmitri Tikhonov#include "lsquic_types.h" 1850aadb33SDmitri Tikhonov#include "lsquic_int_types.h" 1950aadb33SDmitri Tikhonov#include "lsquic_sfcw.h" 2050aadb33SDmitri Tikhonov#include "lsquic_stream.h" 2150aadb33SDmitri Tikhonov#include "lsquic_spi.h" 2250aadb33SDmitri Tikhonov 2350aadb33SDmitri Tikhonov#define LSQUIC_LOGGER_MODULE LSQLM_SPI 2450aadb33SDmitri Tikhonov#define LSQUIC_LOG_CONN_ID iter->spi_cid 2550aadb33SDmitri Tikhonov#include "lsquic_logger.h" 2650aadb33SDmitri Tikhonov 27461e84d8SAmol Deshpande#define SPI_DEBUG(fmt, ...) LSQ_DEBUG("%s: " fmt, iter->spi_name, __VA_ARGS__) 2850aadb33SDmitri Tikhonov 2950aadb33SDmitri Tikhonov#define NEXT_STREAM(stream, off) \ 3050aadb33SDmitri Tikhonov (* (struct lsquic_stream **) ((unsigned char *) (stream) + (off))) 3150aadb33SDmitri Tikhonov 3250aadb33SDmitri Tikhonov 3350aadb33SDmitri Tikhonovstatic void 3450aadb33SDmitri Tikhonovadd_stream_to_spi (struct stream_prio_iter *iter, lsquic_stream_t *stream) 3550aadb33SDmitri Tikhonov{ 3650aadb33SDmitri Tikhonov unsigned set, bit; 3750aadb33SDmitri Tikhonov set = stream->sm_priority >> 6; 3850aadb33SDmitri Tikhonov bit = stream->sm_priority & 0x3F; 3950aadb33SDmitri Tikhonov if (!(iter->spi_set[set] & (1ULL << bit))) 4050aadb33SDmitri Tikhonov { 4150aadb33SDmitri Tikhonov iter->spi_set[set] |= 1ULL << bit; 4250aadb33SDmitri Tikhonov TAILQ_INIT(&iter->spi_streams[ stream->sm_priority ]); 4350aadb33SDmitri Tikhonov } 4450aadb33SDmitri Tikhonov TAILQ_INSERT_TAIL(&iter->spi_streams[ stream->sm_priority ], 4550aadb33SDmitri Tikhonov stream, next_prio_stream); 4650aadb33SDmitri Tikhonov} 4750aadb33SDmitri Tikhonov 4850aadb33SDmitri Tikhonov 4950aadb33SDmitri Tikhonovvoid 50c51ce338SDmitri Tikhonovlsquic_spi_init (struct stream_prio_iter *iter, struct lsquic_stream *first, 51c51ce338SDmitri Tikhonov struct lsquic_stream *last, uintptr_t next_ptr_offset, 5219f667fbSDmitri Tikhonov enum stream_flags onlist_mask, lsquic_cid_t cid, const char *name, 5319f667fbSDmitri Tikhonov int (*filter)(void *filter_ctx, struct lsquic_stream *), 5419f667fbSDmitri Tikhonov void *filter_ctx) 5550aadb33SDmitri Tikhonov{ 5650aadb33SDmitri Tikhonov struct lsquic_stream *stream; 5750aadb33SDmitri Tikhonov unsigned count; 5850aadb33SDmitri Tikhonov 5950aadb33SDmitri Tikhonov iter->spi_cid = cid; 6050aadb33SDmitri Tikhonov iter->spi_name = name ? name : "UNSET"; 6150aadb33SDmitri Tikhonov iter->spi_set[0] = 0; 6250aadb33SDmitri Tikhonov iter->spi_set[1] = 0; 6350aadb33SDmitri Tikhonov iter->spi_set[2] = 0; 6450aadb33SDmitri Tikhonov iter->spi_set[3] = 0; 6550aadb33SDmitri Tikhonov iter->spi_onlist_mask = onlist_mask; 6650aadb33SDmitri Tikhonov iter->spi_cur_prio = 0; 6750aadb33SDmitri Tikhonov iter->spi_prev_stream = NULL; 6850aadb33SDmitri Tikhonov iter->spi_next_stream = NULL; 6950aadb33SDmitri Tikhonov 7050aadb33SDmitri Tikhonov stream = first; 7150aadb33SDmitri Tikhonov count = 0; 7250aadb33SDmitri Tikhonov 7319f667fbSDmitri Tikhonov if (filter) 7419f667fbSDmitri Tikhonov while (1) 7519f667fbSDmitri Tikhonov { 7619f667fbSDmitri Tikhonov if (filter(filter_ctx, stream)) 7719f667fbSDmitri Tikhonov { 7819f667fbSDmitri Tikhonov add_stream_to_spi(iter, stream); 7919f667fbSDmitri Tikhonov ++count; 8019f667fbSDmitri Tikhonov } 8119f667fbSDmitri Tikhonov if (stream == last) 8219f667fbSDmitri Tikhonov break; 8319f667fbSDmitri Tikhonov stream = NEXT_STREAM(stream, next_ptr_offset); 8419f667fbSDmitri Tikhonov } 8519f667fbSDmitri Tikhonov else 8619f667fbSDmitri Tikhonov while (1) 8719f667fbSDmitri Tikhonov { 8819f667fbSDmitri Tikhonov add_stream_to_spi(iter, stream); 8919f667fbSDmitri Tikhonov ++count; 9019f667fbSDmitri Tikhonov if (stream == last) 9119f667fbSDmitri Tikhonov break; 9219f667fbSDmitri Tikhonov stream = NEXT_STREAM(stream, next_ptr_offset); 9319f667fbSDmitri Tikhonov } 94c51ce338SDmitri Tikhonov 9550aadb33SDmitri Tikhonov if (count > 2) 9650aadb33SDmitri Tikhonov SPI_DEBUG("initialized; # elems: %u; sets: [ %016"PRIX64", %016"PRIX64 9750aadb33SDmitri Tikhonov ", %016"PRIX64", %016"PRIX64" ]", count, iter->spi_set[0], 9850aadb33SDmitri Tikhonov iter->spi_set[1], iter->spi_set[2], iter->spi_set[3]); 9950aadb33SDmitri Tikhonov} 10050aadb33SDmitri Tikhonov 10150aadb33SDmitri Tikhonov 10250aadb33SDmitri Tikhonovstatic int 10350aadb33SDmitri Tikhonovfind_and_set_lowest_priority (struct stream_prio_iter *iter) 10450aadb33SDmitri Tikhonov{ 10550aadb33SDmitri Tikhonov unsigned set, prio; 10650aadb33SDmitri Tikhonov uint64_t mask; 10750aadb33SDmitri Tikhonov 10850aadb33SDmitri Tikhonov for (set = 0, prio = 0; set < 4; ++set, prio += 64) 10950aadb33SDmitri Tikhonov if (iter->spi_set[ set ]) 11050aadb33SDmitri Tikhonov break; 11150aadb33SDmitri Tikhonov 11250aadb33SDmitri Tikhonov if (set == 4) 11350aadb33SDmitri Tikhonov { 11450aadb33SDmitri Tikhonov //SPI_DEBUG("%s: cannot find any", __func__); 11550aadb33SDmitri Tikhonov return -1; 11650aadb33SDmitri Tikhonov } 11750aadb33SDmitri Tikhonov 11850aadb33SDmitri Tikhonov mask = iter->spi_set[set]; 11950aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 32) - 1))) { prio += 32; mask >>= 32; } 12050aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 16) - 1))) { prio += 16; mask >>= 16; } 12150aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 8) - 1))) { prio += 8; mask >>= 8; } 12250aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 4) - 1))) { prio += 4; mask >>= 4; } 12350aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 2) - 1))) { prio += 2; mask >>= 2; } 12450aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 1) - 1))) { prio += 1; } 12550aadb33SDmitri Tikhonov 12650aadb33SDmitri Tikhonov#ifndef NDEBUG 12750aadb33SDmitri Tikhonov unsigned bit; 12850aadb33SDmitri Tikhonov set = prio >> 6; 12950aadb33SDmitri Tikhonov bit = prio & 0x3F; 13050aadb33SDmitri Tikhonov assert(iter->spi_set[ set ] & (1ULL << bit)); 13150aadb33SDmitri Tikhonov#endif 13250aadb33SDmitri Tikhonov 13350aadb33SDmitri Tikhonov SPI_DEBUG("%s: prio %u -> %u", __func__, iter->spi_cur_prio, prio); 1342d296031SDmitri Tikhonov iter->spi_cur_prio = (unsigned char) prio; 13550aadb33SDmitri Tikhonov return 0; 13650aadb33SDmitri Tikhonov} 13750aadb33SDmitri Tikhonov 13850aadb33SDmitri Tikhonov 13950aadb33SDmitri Tikhonovstatic int 14050aadb33SDmitri Tikhonovfind_and_set_next_priority (struct stream_prio_iter *iter) 14150aadb33SDmitri Tikhonov{ 14250aadb33SDmitri Tikhonov unsigned set, bit, prio; 14350aadb33SDmitri Tikhonov uint64_t mask; 14450aadb33SDmitri Tikhonov 14550aadb33SDmitri Tikhonov /* Examine values in the same set first */ 14650aadb33SDmitri Tikhonov set = iter->spi_cur_prio >> 6; 14750aadb33SDmitri Tikhonov bit = iter->spi_cur_prio & 0x3F; 14850aadb33SDmitri Tikhonov prio = 64 * set; 14950aadb33SDmitri Tikhonov 15050aadb33SDmitri Tikhonov if (bit < 63) 15150aadb33SDmitri Tikhonov { 15250aadb33SDmitri Tikhonov mask = iter->spi_set[set]; 15350aadb33SDmitri Tikhonov mask &= ~((1ULL << (bit + 1)) - 1); 15450aadb33SDmitri Tikhonov if (mask) 15550aadb33SDmitri Tikhonov goto calc_priority; 15650aadb33SDmitri Tikhonov } 15750aadb33SDmitri Tikhonov 15850aadb33SDmitri Tikhonov ++set; 15950aadb33SDmitri Tikhonov prio += 64; 16050aadb33SDmitri Tikhonov for (; set < 4; ++set, prio += 64) 16150aadb33SDmitri Tikhonov if (iter->spi_set[ set ]) 16250aadb33SDmitri Tikhonov break; 16350aadb33SDmitri Tikhonov 16403fb9352SDmitri Tikhonov if (set >= 4) 16550aadb33SDmitri Tikhonov { 16650aadb33SDmitri Tikhonov //SPI_DEBUG("%s: cannot find any", __func__); 16750aadb33SDmitri Tikhonov return -1; 16850aadb33SDmitri Tikhonov } 16950aadb33SDmitri Tikhonov 17050aadb33SDmitri Tikhonov mask = iter->spi_set[set]; 17150aadb33SDmitri Tikhonov 17250aadb33SDmitri Tikhonov calc_priority: 17350aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 32) - 1))) { prio += 32; mask >>= 32; } 17450aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 16) - 1))) { prio += 16; mask >>= 16; } 17550aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 8) - 1))) { prio += 8; mask >>= 8; } 17650aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 4) - 1))) { prio += 4; mask >>= 4; } 17750aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 2) - 1))) { prio += 2; mask >>= 2; } 17850aadb33SDmitri Tikhonov if (!(mask & ((1ULL << 1) - 1))) { prio += 1; } 17950aadb33SDmitri Tikhonov 18050aadb33SDmitri Tikhonov#ifndef NDEBUG 18150aadb33SDmitri Tikhonov set = prio >> 6; 18250aadb33SDmitri Tikhonov bit = prio & 0x3F; 18350aadb33SDmitri Tikhonov assert(iter->spi_set[ set ] & (1ULL << bit)); 18450aadb33SDmitri Tikhonov#endif 18550aadb33SDmitri Tikhonov 18650aadb33SDmitri Tikhonov SPI_DEBUG("%s: prio %u -> %u", __func__, iter->spi_cur_prio, prio); 1872d296031SDmitri Tikhonov iter->spi_cur_prio = (unsigned char) prio; 18850aadb33SDmitri Tikhonov return 0; 18950aadb33SDmitri Tikhonov} 19050aadb33SDmitri Tikhonov 19150aadb33SDmitri Tikhonov 19250aadb33SDmitri Tikhonov/* Each stream returned by the iterator is processed in some fashion. If, 19350aadb33SDmitri Tikhonov * as a result of this, the stream gets taken off the original list, we 19450aadb33SDmitri Tikhonov * have to follow suit and remove it from the iterator's set of streams. 19550aadb33SDmitri Tikhonov */ 19650aadb33SDmitri Tikhonovstatic void 19750aadb33SDmitri Tikhonovmaybe_evict_prev (struct stream_prio_iter *iter) 19850aadb33SDmitri Tikhonov{ 19950aadb33SDmitri Tikhonov unsigned set, bit; 20050aadb33SDmitri Tikhonov 20150aadb33SDmitri Tikhonov if (0 == (iter->spi_prev_stream->stream_flags & iter->spi_onlist_mask)) 20250aadb33SDmitri Tikhonov { 20350aadb33SDmitri Tikhonov SPI_DEBUG("evict stream %u", iter->spi_prev_stream->id); 20450aadb33SDmitri Tikhonov TAILQ_REMOVE(&iter->spi_streams[ iter->spi_prev_prio ], 20550aadb33SDmitri Tikhonov iter->spi_prev_stream, next_prio_stream); 20650aadb33SDmitri Tikhonov if (TAILQ_EMPTY(&iter->spi_streams[ iter->spi_prev_prio ])) 20750aadb33SDmitri Tikhonov { 20850aadb33SDmitri Tikhonov set = iter->spi_prev_prio >> 6; 20950aadb33SDmitri Tikhonov bit = iter->spi_prev_prio & 0x3F; 21050aadb33SDmitri Tikhonov iter->spi_set[ set ] &= ~(1ULL << bit); 21150aadb33SDmitri Tikhonov SPI_DEBUG("priority %u now has no elements", iter->spi_prev_prio); 21250aadb33SDmitri Tikhonov } 21350aadb33SDmitri Tikhonov iter->spi_prev_stream = NULL; 21450aadb33SDmitri Tikhonov } 21550aadb33SDmitri Tikhonov} 21650aadb33SDmitri Tikhonov 21750aadb33SDmitri Tikhonov 21850aadb33SDmitri Tikhonovlsquic_stream_t * 21950aadb33SDmitri Tikhonovlsquic_spi_first (struct stream_prio_iter *iter) 22050aadb33SDmitri Tikhonov{ 22150aadb33SDmitri Tikhonov lsquic_stream_t *stream; 22250aadb33SDmitri Tikhonov unsigned set, bit; 22350aadb33SDmitri Tikhonov 22450aadb33SDmitri Tikhonov if (iter->spi_prev_stream) 22550aadb33SDmitri Tikhonov maybe_evict_prev(iter); 22650aadb33SDmitri Tikhonov 22750aadb33SDmitri Tikhonov iter->spi_cur_prio = 0; 22850aadb33SDmitri Tikhonov set = iter->spi_cur_prio >> 6; 22950aadb33SDmitri Tikhonov bit = iter->spi_cur_prio & 0x3F; 23050aadb33SDmitri Tikhonov 23150aadb33SDmitri Tikhonov if (!(iter->spi_set[set] & (1ULL << bit))) 23250aadb33SDmitri Tikhonov { 23350aadb33SDmitri Tikhonov if (0 != find_and_set_lowest_priority(iter)) 23450aadb33SDmitri Tikhonov { 23550aadb33SDmitri Tikhonov SPI_DEBUG("%s: return NULL", __func__); 23650aadb33SDmitri Tikhonov return NULL; 23750aadb33SDmitri Tikhonov } 23850aadb33SDmitri Tikhonov } 23950aadb33SDmitri Tikhonov 24050aadb33SDmitri Tikhonov stream = TAILQ_FIRST(&iter->spi_streams[ iter->spi_cur_prio ]); 24150aadb33SDmitri Tikhonov iter->spi_prev_prio = iter->spi_cur_prio; 24250aadb33SDmitri Tikhonov iter->spi_prev_stream = stream; 24350aadb33SDmitri Tikhonov iter->spi_next_stream = TAILQ_NEXT(stream, next_prio_stream); 24450aadb33SDmitri Tikhonov if (stream->id != 1 && stream->id != 3) 24550aadb33SDmitri Tikhonov SPI_DEBUG("%s: return stream %u, priority %u", __func__, stream->id, 24650aadb33SDmitri Tikhonov iter->spi_cur_prio); 24750aadb33SDmitri Tikhonov return stream; 24850aadb33SDmitri Tikhonov} 24950aadb33SDmitri Tikhonov 25050aadb33SDmitri Tikhonov 25150aadb33SDmitri Tikhonovlsquic_stream_t * 25250aadb33SDmitri Tikhonovlsquic_spi_next (struct stream_prio_iter *iter) 25350aadb33SDmitri Tikhonov{ 25450aadb33SDmitri Tikhonov lsquic_stream_t *stream; 25550aadb33SDmitri Tikhonov 25650aadb33SDmitri Tikhonov if (iter->spi_prev_stream) 25750aadb33SDmitri Tikhonov maybe_evict_prev(iter); 25850aadb33SDmitri Tikhonov 25950aadb33SDmitri Tikhonov stream = iter->spi_next_stream; 26050aadb33SDmitri Tikhonov if (stream) 26150aadb33SDmitri Tikhonov { 26250aadb33SDmitri Tikhonov assert(iter->spi_prev_prio == iter->spi_cur_prio); 26350aadb33SDmitri Tikhonov iter->spi_prev_stream = stream; 26450aadb33SDmitri Tikhonov iter->spi_next_stream = TAILQ_NEXT(stream, next_prio_stream); 26550aadb33SDmitri Tikhonov if (stream->id != 1 && stream->id != 3) 26650aadb33SDmitri Tikhonov SPI_DEBUG("%s: return stream %u, priority %u", __func__, stream->id, 26750aadb33SDmitri Tikhonov iter->spi_cur_prio); 26850aadb33SDmitri Tikhonov return stream; 26950aadb33SDmitri Tikhonov } 27050aadb33SDmitri Tikhonov 27150aadb33SDmitri Tikhonov if (0 != find_and_set_next_priority(iter)) 27250aadb33SDmitri Tikhonov { 27350aadb33SDmitri Tikhonov //SPI_DEBUG("%s: return NULL", __func__); 27450aadb33SDmitri Tikhonov return NULL; 27550aadb33SDmitri Tikhonov } 27650aadb33SDmitri Tikhonov 27750aadb33SDmitri Tikhonov stream = TAILQ_FIRST(&iter->spi_streams[ iter->spi_cur_prio ]); 27850aadb33SDmitri Tikhonov iter->spi_prev_prio = iter->spi_cur_prio; 27950aadb33SDmitri Tikhonov iter->spi_prev_stream = stream; 28050aadb33SDmitri Tikhonov iter->spi_next_stream = TAILQ_NEXT(stream, next_prio_stream); 28150aadb33SDmitri Tikhonov 282c51ce338SDmitri Tikhonov if (!lsquic_stream_is_critical(stream)) 28350aadb33SDmitri Tikhonov SPI_DEBUG("%s: return stream %u, priority %u", __func__, stream->id, 28450aadb33SDmitri Tikhonov iter->spi_cur_prio); 28550aadb33SDmitri Tikhonov return stream; 28650aadb33SDmitri Tikhonov} 28750aadb33SDmitri Tikhonov 28850aadb33SDmitri Tikhonov 289c51ce338SDmitri Tikhonovstatic int 290c51ce338SDmitri Tikhonovhave_non_critical_streams (const struct stream_prio_iter *iter) 291c51ce338SDmitri Tikhonov{ 292c51ce338SDmitri Tikhonov const struct lsquic_stream *stream; 293c51ce338SDmitri Tikhonov TAILQ_FOREACH(stream, &iter->spi_streams[ iter->spi_cur_prio ], 294c51ce338SDmitri Tikhonov next_prio_stream) 295c51ce338SDmitri Tikhonov if (!lsquic_stream_is_critical(stream)) 296c51ce338SDmitri Tikhonov return 1; 297c51ce338SDmitri Tikhonov return 0; 298c51ce338SDmitri Tikhonov} 299c51ce338SDmitri Tikhonov 300c51ce338SDmitri Tikhonov 301c51ce338SDmitri Tikhonovstatic void 302c51ce338SDmitri Tikhonovspi_drop_high_or_non_high (struct stream_prio_iter *iter, int drop_high) 303c51ce338SDmitri Tikhonov{ 304c51ce338SDmitri Tikhonov uint64_t new_set[ sizeof(iter->spi_set) / sizeof(iter->spi_set[0]) ]; 305c51ce338SDmitri Tikhonov unsigned bit, set, n; 306c51ce338SDmitri Tikhonov 307c51ce338SDmitri Tikhonov memset(new_set, 0, sizeof(new_set)); 308c51ce338SDmitri Tikhonov 309c51ce338SDmitri Tikhonov find_and_set_lowest_priority(iter); 310c51ce338SDmitri Tikhonov set = iter->spi_cur_prio >> 6; 311c51ce338SDmitri Tikhonov bit = iter->spi_cur_prio & 0x3F; 312c51ce338SDmitri Tikhonov new_set[set] |= 1ULL << bit; 313c51ce338SDmitri Tikhonov 314c51ce338SDmitri Tikhonov if (!have_non_critical_streams(iter)) 315c51ce338SDmitri Tikhonov { 316c51ce338SDmitri Tikhonov ++iter->spi_cur_prio; 317c51ce338SDmitri Tikhonov find_and_set_lowest_priority(iter); 318c51ce338SDmitri Tikhonov set = iter->spi_cur_prio >> 6; 319c51ce338SDmitri Tikhonov bit = iter->spi_cur_prio & 0x3F; 320c51ce338SDmitri Tikhonov new_set[set] |= 1ULL << bit; 321c51ce338SDmitri Tikhonov } 322c51ce338SDmitri Tikhonov 323c51ce338SDmitri Tikhonov for (n = 0; n < sizeof(new_set) / sizeof(new_set[0]); ++n) 324c51ce338SDmitri Tikhonov if (drop_high) 325c51ce338SDmitri Tikhonov iter->spi_set[n] &= ~new_set[n]; 326c51ce338SDmitri Tikhonov else 327c51ce338SDmitri Tikhonov iter->spi_set[n] = new_set[n]; 328c51ce338SDmitri Tikhonov} 329c51ce338SDmitri Tikhonov 330c51ce338SDmitri Tikhonov 331c51ce338SDmitri Tikhonovvoid 332c51ce338SDmitri Tikhonovlsquic_spi_drop_high (struct stream_prio_iter *iter) 333c51ce338SDmitri Tikhonov{ 334c51ce338SDmitri Tikhonov spi_drop_high_or_non_high(iter, 1); 335c51ce338SDmitri Tikhonov} 336c51ce338SDmitri Tikhonov 337c51ce338SDmitri Tikhonov 33850aadb33SDmitri Tikhonovvoid 339c51ce338SDmitri Tikhonovlsquic_spi_drop_non_high (struct stream_prio_iter *iter) 34050aadb33SDmitri Tikhonov{ 341c51ce338SDmitri Tikhonov spi_drop_high_or_non_high(iter, 0); 34250aadb33SDmitri Tikhonov} 343