ring: remove watermark support
Remove the watermark support. A future commit will add support for having enqueue functions return the amount of free space in the ring, which will allow applications to implement their own watermark checks, while also being more useful to the app. Signed-off-by: Bruce Richardson <bruce.richardson@intel.com> Reviewed-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> Acked-by: Olivier Matz <olivier.matz@6wind.com>
This commit is contained in:
parent
82cb88375c
commit
77dd306427
@ -102,14 +102,6 @@ Name
|
||||
A ring is identified by a unique name.
|
||||
It is not possible to create two rings with the same name (rte_ring_create() returns NULL if this is attempted).
|
||||
|
||||
Water Marking
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The ring can have a high water mark (threshold).
|
||||
Once an enqueue operation reaches the high water mark, the producer is notified, if the water mark is configured.
|
||||
|
||||
This mechanism can be used, for example, to exert a back pressure on I/O to inform the LAN to PAUSE.
|
||||
|
||||
Use Cases
|
||||
---------
|
||||
|
||||
|
@ -135,6 +135,8 @@ API Changes
|
||||
* removed the build-time setting ``CONFIG_RTE_RING_SPLIT_PROD_CONS``
|
||||
* removed the build-time setting ``CONFIG_RTE_LIBRTE_RING_DEBUG``
|
||||
* removed the build-time setting ``CONFIG_RTE_RING_PAUSE_REP_COUNT``
|
||||
* removed the function ``rte_ring_set_water_mark`` as part of a general
|
||||
removal of watermarks support in the library.
|
||||
|
||||
ABI Changes
|
||||
-----------
|
||||
|
@ -81,7 +81,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ptpclient
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_METER) += qos_meter
|
||||
DIRS-$(CONFIG_RTE_LIBRTE_SCHED) += qos_sched
|
||||
DIRS-y += quota_watermark
|
||||
#DIRS-y += quota_watermark
|
||||
DIRS-$(CONFIG_RTE_ETHDEV_RXTX_CALLBACKS) += rxtx_callbacks
|
||||
DIRS-y += skeleton
|
||||
ifeq ($(CONFIG_RTE_LIBRTE_HASH),y)
|
||||
|
@ -138,7 +138,6 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
|
||||
if (ret < 0 || ret >= (int)sizeof(r->name))
|
||||
return -ENAMETOOLONG;
|
||||
r->flags = flags;
|
||||
r->watermark = count;
|
||||
r->prod.single = !!(flags & RING_F_SP_ENQ);
|
||||
r->cons.single = !!(flags & RING_F_SC_DEQ);
|
||||
r->size = count;
|
||||
@ -256,24 +255,6 @@ rte_ring_free(struct rte_ring *r)
|
||||
rte_free(te);
|
||||
}
|
||||
|
||||
/*
|
||||
* change the high water mark. If *count* is 0, water marking is
|
||||
* disabled
|
||||
*/
|
||||
int
|
||||
rte_ring_set_water_mark(struct rte_ring *r, unsigned count)
|
||||
{
|
||||
if (count >= r->size)
|
||||
return -EINVAL;
|
||||
|
||||
/* if count is 0, disable the watermarking */
|
||||
if (count == 0)
|
||||
count = r->size;
|
||||
|
||||
r->watermark = count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dump the status of the ring on the console */
|
||||
void
|
||||
rte_ring_dump(FILE *f, const struct rte_ring *r)
|
||||
@ -287,10 +268,6 @@ rte_ring_dump(FILE *f, const struct rte_ring *r)
|
||||
fprintf(f, " ph=%"PRIu32"\n", r->prod.head);
|
||||
fprintf(f, " used=%u\n", rte_ring_count(r));
|
||||
fprintf(f, " avail=%u\n", rte_ring_free_count(r));
|
||||
if (r->watermark == r->size)
|
||||
fprintf(f, " watermark=0\n");
|
||||
else
|
||||
fprintf(f, " watermark=%"PRIu32"\n", r->watermark);
|
||||
}
|
||||
|
||||
/* dump the status of all rings on the console */
|
||||
|
@ -153,7 +153,6 @@ struct rte_ring {
|
||||
/**< Memzone, if any, containing the rte_ring */
|
||||
uint32_t size; /**< Size of ring. */
|
||||
uint32_t mask; /**< Mask (size-1) of ring. */
|
||||
uint32_t watermark; /**< Max items before EDQUOT in producer. */
|
||||
|
||||
/** Ring producer status. */
|
||||
struct rte_ring_headtail prod __rte_aligned(PROD_ALIGN);
|
||||
@ -168,7 +167,6 @@ struct rte_ring {
|
||||
|
||||
#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
|
||||
#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
|
||||
#define RTE_RING_QUOT_EXCEED (1 << 31) /**< Quota exceed for burst ops */
|
||||
#define RTE_RING_SZ_MASK (unsigned)(0x0fffffff) /**< Ring size mask */
|
||||
|
||||
/**
|
||||
@ -273,26 +271,6 @@ struct rte_ring *rte_ring_create(const char *name, unsigned count,
|
||||
*/
|
||||
void rte_ring_free(struct rte_ring *r);
|
||||
|
||||
/**
|
||||
* Change the high water mark.
|
||||
*
|
||||
* If *count* is 0, water marking is disabled. Otherwise, it is set to the
|
||||
* *count* value. The *count* value must be greater than 0 and less
|
||||
* than the ring size.
|
||||
*
|
||||
* This function can be called at any time (not necessarily at
|
||||
* initialization).
|
||||
*
|
||||
* @param r
|
||||
* A pointer to the ring structure.
|
||||
* @param count
|
||||
* The new water mark value.
|
||||
* @return
|
||||
* - 0: Success; water mark changed.
|
||||
* - -EINVAL: Invalid water mark value.
|
||||
*/
|
||||
int rte_ring_set_water_mark(struct rte_ring *r, unsigned count);
|
||||
|
||||
/**
|
||||
* Dump the status of the ring to a file.
|
||||
*
|
||||
@ -374,8 +352,6 @@ void rte_ring_dump(FILE *f, const struct rte_ring *r);
|
||||
* Depend on the behavior value
|
||||
* if behavior = RTE_RING_QUEUE_FIXED
|
||||
* - 0: Success; objects enqueue.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued.
|
||||
* if behavior = RTE_RING_QUEUE_VARIABLE
|
||||
* - n: Actual number of objects enqueued.
|
||||
@ -390,7 +366,6 @@ __rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table,
|
||||
int success;
|
||||
unsigned int i;
|
||||
uint32_t mask = r->mask;
|
||||
int ret;
|
||||
|
||||
/* Avoid the unnecessary cmpset operation below, which is also
|
||||
* potentially harmful when n equals 0. */
|
||||
@ -431,13 +406,6 @@ __rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table,
|
||||
ENQUEUE_PTRS();
|
||||
rte_smp_wmb();
|
||||
|
||||
/* if we exceed the watermark */
|
||||
if (unlikely(((mask + 1) - free_entries + n) > r->watermark))
|
||||
ret = (behavior == RTE_RING_QUEUE_FIXED) ? -EDQUOT :
|
||||
(int)(n | RTE_RING_QUOT_EXCEED);
|
||||
else
|
||||
ret = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : n;
|
||||
|
||||
/*
|
||||
* If there are other enqueues in progress that preceded us,
|
||||
* we need to wait for them to complete
|
||||
@ -446,7 +414,7 @@ __rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table,
|
||||
rte_pause();
|
||||
|
||||
r->prod.tail = prod_next;
|
||||
return ret;
|
||||
return (behavior == RTE_RING_QUEUE_FIXED) ? 0 : n;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -465,8 +433,6 @@ __rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table,
|
||||
* Depend on the behavior value
|
||||
* if behavior = RTE_RING_QUEUE_FIXED
|
||||
* - 0: Success; objects enqueue.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued.
|
||||
* if behavior = RTE_RING_QUEUE_VARIABLE
|
||||
* - n: Actual number of objects enqueued.
|
||||
@ -479,7 +445,6 @@ __rte_ring_sp_do_enqueue(struct rte_ring *r, void * const *obj_table,
|
||||
uint32_t prod_next, free_entries;
|
||||
unsigned int i;
|
||||
uint32_t mask = r->mask;
|
||||
int ret;
|
||||
|
||||
prod_head = r->prod.head;
|
||||
cons_tail = r->cons.tail;
|
||||
@ -508,15 +473,8 @@ __rte_ring_sp_do_enqueue(struct rte_ring *r, void * const *obj_table,
|
||||
ENQUEUE_PTRS();
|
||||
rte_smp_wmb();
|
||||
|
||||
/* if we exceed the watermark */
|
||||
if (unlikely(((mask + 1) - free_entries + n) > r->watermark))
|
||||
ret = (behavior == RTE_RING_QUEUE_FIXED) ? -EDQUOT :
|
||||
(int)(n | RTE_RING_QUOT_EXCEED);
|
||||
else
|
||||
ret = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : n;
|
||||
|
||||
r->prod.tail = prod_next;
|
||||
return ret;
|
||||
return (behavior == RTE_RING_QUEUE_FIXED) ? 0 : n;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -682,8 +640,6 @@ __rte_ring_sc_do_dequeue(struct rte_ring *r, void **obj_table,
|
||||
* The number of objects to add in the ring from the obj_table.
|
||||
* @return
|
||||
* - 0: Success; objects enqueue.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue, no object is enqueued.
|
||||
*/
|
||||
static inline int __attribute__((always_inline))
|
||||
@ -704,8 +660,6 @@ rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
|
||||
* The number of objects to add in the ring from the obj_table.
|
||||
* @return
|
||||
* - 0: Success; objects enqueued.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
|
||||
*/
|
||||
static inline int __attribute__((always_inline))
|
||||
@ -730,8 +684,6 @@ rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
|
||||
* The number of objects to add in the ring from the obj_table.
|
||||
* @return
|
||||
* - 0: Success; objects enqueued.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
|
||||
*/
|
||||
static inline int __attribute__((always_inline))
|
||||
@ -756,8 +708,6 @@ rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
|
||||
* A pointer to the object to be added.
|
||||
* @return
|
||||
* - 0: Success; objects enqueued.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
|
||||
*/
|
||||
static inline int __attribute__((always_inline))
|
||||
@ -775,8 +725,6 @@ rte_ring_mp_enqueue(struct rte_ring *r, void *obj)
|
||||
* A pointer to the object to be added.
|
||||
* @return
|
||||
* - 0: Success; objects enqueued.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
|
||||
*/
|
||||
static inline int __attribute__((always_inline))
|
||||
@ -798,8 +746,6 @@ rte_ring_sp_enqueue(struct rte_ring *r, void *obj)
|
||||
* A pointer to the object to be added.
|
||||
* @return
|
||||
* - 0: Success; objects enqueued.
|
||||
* - -EDQUOT: Quota exceeded. The objects have been enqueued, but the
|
||||
* high water mark is exceeded.
|
||||
* - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
|
||||
*/
|
||||
static inline int __attribute__((always_inline))
|
||||
|
@ -292,11 +292,4 @@ def ring_autotest(child, test_name):
|
||||
elif index == 2:
|
||||
return -1, "Fail [Timeout]"
|
||||
|
||||
child.sendline("set_watermark test 100")
|
||||
child.sendline("dump_ring test")
|
||||
index = child.expect([" watermark=100",
|
||||
pexpect.TIMEOUT], timeout=1)
|
||||
if index != 0:
|
||||
return -1, "Fail [Bad watermark]"
|
||||
|
||||
return 0, "Success"
|
||||
|
@ -228,57 +228,6 @@ cmdline_parse_inst_t cmd_dump_one = {
|
||||
|
||||
/****************/
|
||||
|
||||
struct cmd_set_ring_result {
|
||||
cmdline_fixed_string_t set;
|
||||
cmdline_fixed_string_t name;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
static void cmd_set_ring_parsed(void *parsed_result, struct cmdline *cl,
|
||||
__attribute__((unused)) void *data)
|
||||
{
|
||||
struct cmd_set_ring_result *res = parsed_result;
|
||||
struct rte_ring *r;
|
||||
int ret;
|
||||
|
||||
r = rte_ring_lookup(res->name);
|
||||
if (r == NULL) {
|
||||
cmdline_printf(cl, "Cannot find ring\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(res->set, "set_watermark")) {
|
||||
ret = rte_ring_set_water_mark(r, res->value);
|
||||
if (ret != 0)
|
||||
cmdline_printf(cl, "Cannot set water mark\n");
|
||||
}
|
||||
}
|
||||
|
||||
cmdline_parse_token_string_t cmd_set_ring_set =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, set,
|
||||
"set_watermark");
|
||||
|
||||
cmdline_parse_token_string_t cmd_set_ring_name =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, name, NULL);
|
||||
|
||||
cmdline_parse_token_num_t cmd_set_ring_value =
|
||||
TOKEN_NUM_INITIALIZER(struct cmd_set_ring_result, value, UINT32);
|
||||
|
||||
cmdline_parse_inst_t cmd_set_ring = {
|
||||
.f = cmd_set_ring_parsed, /* function to call */
|
||||
.data = NULL, /* 2nd arg of func */
|
||||
.help_str = "set watermark: "
|
||||
"set_watermark <ring_name> <value>",
|
||||
.tokens = { /* token list, NULL terminated */
|
||||
(void *)&cmd_set_ring_set,
|
||||
(void *)&cmd_set_ring_name,
|
||||
(void *)&cmd_set_ring_value,
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
/****************/
|
||||
|
||||
struct cmd_quit_result {
|
||||
cmdline_fixed_string_t quit;
|
||||
};
|
||||
@ -419,7 +368,6 @@ cmdline_parse_ctx_t main_ctx[] = {
|
||||
(cmdline_parse_inst_t *)&cmd_autotest,
|
||||
(cmdline_parse_inst_t *)&cmd_dump,
|
||||
(cmdline_parse_inst_t *)&cmd_dump_one,
|
||||
(cmdline_parse_inst_t *)&cmd_set_ring,
|
||||
(cmdline_parse_inst_t *)&cmd_quit,
|
||||
(cmdline_parse_inst_t *)&cmd_set_rxtx,
|
||||
(cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,
|
||||
|
@ -78,21 +78,6 @@
|
||||
* - Dequeue one object, two objects, MAX_BULK objects
|
||||
* - Check that dequeued pointers are correct
|
||||
*
|
||||
* - Test watermark and default bulk enqueue/dequeue:
|
||||
*
|
||||
* - Set watermark
|
||||
* - Set default bulk value
|
||||
* - Enqueue objects, check that -EDQUOT is returned when
|
||||
* watermark is exceeded
|
||||
* - Check that dequeued pointers are correct
|
||||
*
|
||||
* #. Check live watermark change
|
||||
*
|
||||
* - Start a loop on another lcore that will enqueue and dequeue
|
||||
* objects in a ring. It will monitor the value of watermark.
|
||||
* - At the same time, change the watermark on the master lcore.
|
||||
* - The slave lcore will check that watermark changes from 16 to 32.
|
||||
*
|
||||
* #. Performance tests.
|
||||
*
|
||||
* Tests done in test_ring_perf.c
|
||||
@ -115,123 +100,6 @@ static struct rte_ring *r;
|
||||
|
||||
#define TEST_RING_FULL_EMTPY_ITER 8
|
||||
|
||||
static int
|
||||
check_live_watermark_change(__attribute__((unused)) void *dummy)
|
||||
{
|
||||
uint64_t hz = rte_get_timer_hz();
|
||||
void *obj_table[MAX_BULK];
|
||||
unsigned watermark, watermark_old = 16;
|
||||
uint64_t cur_time, end_time;
|
||||
int64_t diff = 0;
|
||||
int i, ret;
|
||||
unsigned count = 4;
|
||||
|
||||
/* init the object table */
|
||||
memset(obj_table, 0, sizeof(obj_table));
|
||||
end_time = rte_get_timer_cycles() + (hz / 4);
|
||||
|
||||
/* check that bulk and watermark are 4 and 32 (respectively) */
|
||||
while (diff >= 0) {
|
||||
|
||||
/* add in ring until we reach watermark */
|
||||
ret = 0;
|
||||
for (i = 0; i < 16; i ++) {
|
||||
if (ret != 0)
|
||||
break;
|
||||
ret = rte_ring_enqueue_bulk(r, obj_table, count);
|
||||
}
|
||||
|
||||
if (ret != -EDQUOT) {
|
||||
printf("Cannot enqueue objects, or watermark not "
|
||||
"reached (ret=%d)\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read watermark, the only change allowed is from 16 to 32 */
|
||||
watermark = r->watermark;
|
||||
if (watermark != watermark_old &&
|
||||
(watermark_old != 16 || watermark != 32)) {
|
||||
printf("Bad watermark change %u -> %u\n", watermark_old,
|
||||
watermark);
|
||||
return -1;
|
||||
}
|
||||
watermark_old = watermark;
|
||||
|
||||
/* dequeue objects from ring */
|
||||
while (i--) {
|
||||
ret = rte_ring_dequeue_bulk(r, obj_table, count);
|
||||
if (ret != 0) {
|
||||
printf("Cannot dequeue (ret=%d)\n", ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
cur_time = rte_get_timer_cycles();
|
||||
diff = end_time - cur_time;
|
||||
}
|
||||
|
||||
if (watermark_old != 32 ) {
|
||||
printf(" watermark was not updated (wm=%u)\n",
|
||||
watermark_old);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_live_watermark_change(void)
|
||||
{
|
||||
unsigned lcore_id = rte_lcore_id();
|
||||
unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1);
|
||||
|
||||
printf("Test watermark live modification\n");
|
||||
rte_ring_set_water_mark(r, 16);
|
||||
|
||||
/* launch a thread that will enqueue and dequeue, checking
|
||||
* watermark and quota */
|
||||
rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2);
|
||||
|
||||
rte_delay_ms(100);
|
||||
rte_ring_set_water_mark(r, 32);
|
||||
rte_delay_ms(100);
|
||||
|
||||
if (rte_eal_wait_lcore(lcore_id2) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test for catch on invalid watermark values */
|
||||
static int
|
||||
test_set_watermark( void ){
|
||||
unsigned count;
|
||||
int setwm;
|
||||
|
||||
struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex");
|
||||
if(r == NULL){
|
||||
printf( " ring lookup failed\n" );
|
||||
goto error;
|
||||
}
|
||||
count = r->size * 2;
|
||||
setwm = rte_ring_set_water_mark(r, count);
|
||||
if (setwm != -EINVAL){
|
||||
printf("Test failed to detect invalid watermark count value\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
rte_ring_set_water_mark(r, count);
|
||||
if (r->watermark != r->size) {
|
||||
printf("Test failed to detect invalid watermark count value\n");
|
||||
goto error;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* helper routine for test_ring_basic
|
||||
*/
|
||||
@ -418,8 +286,7 @@ test_ring_basic(void)
|
||||
cur_src = src;
|
||||
cur_dst = dst;
|
||||
|
||||
printf("test watermark and default bulk enqueue / dequeue\n");
|
||||
rte_ring_set_water_mark(r, 20);
|
||||
printf("test default bulk enqueue / dequeue\n");
|
||||
num_elems = 16;
|
||||
|
||||
cur_src = src;
|
||||
@ -433,8 +300,8 @@ test_ring_basic(void)
|
||||
}
|
||||
ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
|
||||
cur_src += num_elems;
|
||||
if (ret != -EDQUOT) {
|
||||
printf("Watermark not exceeded\n");
|
||||
if (ret != 0) {
|
||||
printf("Cannot enqueue\n");
|
||||
goto fail;
|
||||
}
|
||||
ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
|
||||
@ -930,16 +797,6 @@ test_ring(void)
|
||||
return -1;
|
||||
|
||||
/* basic operations */
|
||||
if (test_live_watermark_change() < 0)
|
||||
return -1;
|
||||
|
||||
if ( test_set_watermark() < 0){
|
||||
printf ("Test failed to detect invalid parameter\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
printf ( "Test detected forced bad watermark values\n");
|
||||
|
||||
if ( test_create_count_odd() < 0){
|
||||
printf ("Test failed to detect odd count\n");
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user