57#include "em_libconfig.h"
82 EM_MAX_QUEUE_GROUPS__TOO_SMALL);
86static em_queue_group_t default_queue_group_create(
void);
87static em_queue_group_t default_queue_group_join(
void);
89static em_queue_group_t
90queue_group_create_escope(
const char *name,
const em_core_mask_t *mask,
92 em_queue_group_t requested_queue_group,
98static void q_grp_create_done_callback(
void *arg_ptr);
99static void q_grp_create_sync_done_callback(
void *arg_ptr);
105static void q_grp_modify_done_callback(
void *arg_ptr);
106static void q_grp_modify_sync_done_callback(
void *arg_ptr);
110static void q_grp_delete_done_callback(
void *arg_ptr);
111static void q_grp_delete_sync_done_callback(
void *arg_ptr);
127queue_group_poolelem2qgrpelem(
objpool_elem_t *
const queue_group_pool_elem)
134read_config_file(
void)
136 const char *conf_str;
137 bool val_bool =
false;
140 EM_PRINT(
"EM queue group config:\n");
145 conf_str =
"queue_group.create_core_queue_groups";
146 ret = em_libconfig_lookup_bool(&
em_shm->libconfig, conf_str, &val_bool);
147 if (unlikely(!ret)) {
148 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
152 em_shm->
opt.queue_group.create_core_queue_groups = val_bool;
153 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
159 conf_str =
"queue_group.term_local_flush_orphans";
160 ret = em_libconfig_lookup_bool(&
em_shm->libconfig, conf_str, &val_bool);
161 if (unlikely(!ret)) {
162 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
166 em_shm->
opt.queue_group.term_local_flush_orphans = val_bool;
167 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
183 if (read_config_file())
194 odp_ticketlock_init(&queue_group_elem->
lock);
201 ret = objpool_init(&queue_group_pool->
objpool_rsvd, num_subpools);
207 objpool_add(&queue_group_pool->
objpool_rsvd, i % num_subpools,
215 ret = objpool_init(&queue_group_pool->
objpool_dyn, num_subpools);
221 objpool_add(&queue_group_pool->
objpool_dyn, i % num_subpools,
228 em_queue_group_t default_queue_group = default_queue_group_create();
231 EM_LOG(EM_LOG_ERR,
"default_queue_group_create() failed!\n");
243 em_queue_group_t def_qgrp = default_queue_group_join();
246 EM_LOG(EM_LOG_ERR,
"default_queue_group_join() failed!\n");
253 if (
em_shm->
opt.queue_group.create_core_queue_groups) {
257 EM_LOG(EM_LOG_ERR,
"core_queue_group_create():%" PRI_STAT
"\n", stat);
264 stat = core_queue_group_join();
267 EM_LOG(EM_LOG_ERR,
"core_queue_group_join():%" PRI_STAT
"\n", stat);
287 if (unlikely(!qgrp_elem)) {
288 EM_LOG(EM_LOG_ERR,
"%s(): qgrp_elem NULL\n", __func__);
295 "Bad state qgrp:%" PRI_QGRP " delete is ongoing\n", qgrp);
299 if (unlikely(odp_ticketlock_is_locked(&qgrp_elem->
lock))) {
301 EM_LOG(EM_LOG_ERR,
"Bad state qgrp:%" PRI_QGRP " - lock is locked\n", qgrp);
308 if (unlikely(ret != 0)) {
310 "ODP schedule group destroy failed qgrp:%"
335static em_queue_group_t
336queue_group_alloc(em_queue_group_t queue_group)
348 qgrp_pool_elem = objpool_rem(&qgrp_pools->
objpool_dyn, core);
350 if (unlikely(qgrp_pool_elem == NULL)) {
352 qgrp_pool_elem = objpool_rem(&qgrp_pools->
objpool_rsvd, core);
353 if (unlikely(qgrp_pool_elem == NULL))
357 qgrp_elem = queue_group_poolelem2qgrpelem(qgrp_pool_elem);
365 qgrp_elem = queue_group_elem_get(queue_group);
366 if (unlikely(qgrp_elem == NULL))
369 odp_ticketlock_lock(&qgrp_elem->
lock);
371 if (queue_group_allocated(qgrp_elem)) {
372 odp_ticketlock_unlock(&qgrp_elem->
lock);
379 odp_ticketlock_unlock(&qgrp_elem->
lock);
380 if (unlikely(ret != 0))
397queue_group_free(em_queue_group_t queue_group)
400 queue_group_elem_get(queue_group);
402 &
em_shm->queue_group_pool.objpool_rsvd :
403 &
em_shm->queue_group_pool.objpool_dyn;
405 if (unlikely(queue_group_elem == NULL))
421static odp_schedule_group_t
422create_odp_schedule_group(
const char *name,
const odp_thrmask_t *thrmask)
424 odp_schedule_group_t odp_sched_group = ODP_SCHED_GROUP_INVALID;
426 odp_schedule_group_param_t param;
428 odp_schedule_group_param_init(¶m);
431 param.cache_stash_hints.common.regions.event_data_l2 = 1;
432 param.cache_stash_hints.common.regions.event_user_area_l2 = 1;
433 param.cache_stash_hints.common.regions.queue_context_l2 = 1;
436 param.cache_stash_hints.common.event_data.l2.offset = 0;
437 param.cache_stash_hints.common.event_data.l2.len = ODP_CACHE_LINE_SIZE;
439 param.cache_stash_hints.common.event_user_area.l2.offset = 0;
440 param.cache_stash_hints.common.event_user_area.l2.len =
sizeof(
event_hdr_t);
442 param.cache_stash_hints.common.queue_context.l2.offset = 0;
443 param.cache_stash_hints.common.queue_context.l2.len = MIN(
sizeof(
queue_elem_t),
444 ODP_CACHE_LINE_SIZE);
445 odp_sched_group = odp_schedule_group_create_2(name, thrmask, ¶m);
446 return odp_sched_group;
452static em_queue_group_t default_queue_group_create(
void)
454 em_queue_group_t default_qgrp;
457 odp_thrmask_t zero_thrmask;
458 odp_schedule_group_t odp_sched_group;
465 if (unlikely(default_qgrp_elem == NULL))
471 odp_thrmask_zero(&zero_thrmask);
484 if (unlikely(odp_sched_group == ODP_SCHED_GROUP_INVALID)) {
485 DBG_PRINT(
"ODP schedule group creation failed for 'EM_QUEUE_GROUP_DEFAULT'\n");
500static em_queue_group_t default_queue_group_join(
void)
503 odp_thrmask_t odp_joinmask;
505 const int odp_thr = odp_thread_id();
509 if (unlikely(!default_qgrp_elem))
513 odp_thrmask_zero(&odp_joinmask);
514 odp_thrmask_set(&odp_joinmask, odp_thr);
516 odp_ticketlock_lock(&default_qgrp_elem->
lock);
521 odp_ticketlock_unlock(&default_qgrp_elem->
lock);
536void queue_group_join_all(
void)
544 odp_ticketlock_lock(&qgrp_elem->
lock);
546 int allocated = queue_group_allocated(qgrp_elem);
549 if (allocated && !ongoing_delete &&
552 q_grp_add_core(qgrp_elem);
554 odp_ticketlock_unlock(&qgrp_elem->
lock);
561list_node_to_qgrp_elem(
const list_node_t *
const list_node)
566 return likely(list_node != NULL) ? qgrp_elem : NULL;
581void queue_group_leave_all(
bool flush_orphan_qgrps)
595 list_init(&qgrp_list);
598 odp_ticketlock_lock(&qgrp_elem->
lock);
600 int allocated = queue_group_allocated(qgrp_elem);
602 bool do_unlock =
true;
604 if (allocated && !ongoing_delete &&
606 if (flush_orphan_qgrps &&
615 q_grp_rem_core(qgrp_elem);
620 odp_ticketlock_unlock(&qgrp_elem->
lock);
624 qgrp_elem = queue_group_elem_get(qgrp);
628 if (!list_is_empty(&qgrp_list)) {
636 odp_schedule_resume();
638 flush_scheduler_events();
642 odp_schedule_pause();
644 flush_scheduler_events();
656 while ((list_node = list_rem_first(&qgrp_list)) != NULL) {
657 qgrp_elem = list_node_to_qgrp_elem(list_node);
659 q_grp_rem_core(qgrp_elem);
662 odp_ticketlock_unlock(&qgrp_elem->
lock);
669 em_queue_group_t qgrp;
670 em_queue_group_t qgrp_req;
673 odp_thrmask_t zero_thrmask;
674 odp_schedule_group_t odp_sched_group;
678 core_queue_grp_name(core, qgrp_name,
sizeof(qgrp_name));
682 DBG_PRINT(
"%s(): core:%d, %s already created - reusing\n",
683 __func__, core, qgrp_name);
685 qgrp_elem = queue_group_elem_get(qgrp);
687 if (unlikely(!qgrp_elem || !queue_group_allocated(qgrp_elem))) {
688 DBG_PRINT(
"%s(): qgrp_elem invalid for core-qgrp:%d\n",
696 qgrp_req = qgrp_idx2hdl(core);
697 qgrp = queue_group_alloc(qgrp_req);
699 DBG_PRINT(
"queue_group_alloc() fails for core-qgrp:%d\n", core);
703 qgrp_elem = queue_group_elem_get(qgrp);
704 if (unlikely(qgrp_elem == NULL)) {
705 DBG_PRINT(
"qgrp_elem NULL for core-qgrp:%d\n", core);
713 odp_thrmask_zero(&zero_thrmask);
723 odp_sched_group = create_odp_schedule_group(qgrp_name, &zero_thrmask);
724 if (unlikely(odp_sched_group == ODP_SCHED_GROUP_INVALID)) {
725 DBG_PRINT(
"ODP schedule group creation failed for core-qgrp:%d\n", core);
738 const int odp_thr = odp_thread_id();
740 core_queue_grp_name(core, qgrp_name,
sizeof(qgrp_name));
745 DBG_PRINT(
"%s(): core:%d, %s not found\n", __func__, core, qgrp_name);
751 if (unlikely(!qgrp_elem)) {
752 DBG_PRINT(
"%s(): qgrp_elem NULL for core-qgrp:%d\n",
758 odp_thrmask_t odp_joinmask;
760 odp_thrmask_zero(&odp_joinmask);
761 odp_thrmask_set(&odp_joinmask, odp_thr);
763 odp_ticketlock_lock(&qgrp_elem->
lock);
767 odp_ticketlock_unlock(&qgrp_elem->
lock);
770 DBG_PRINT(
"%s(): odp_schedule_group_join():%d, core-qgrp:%d\n",
771 __func__, ret, core);
784static em_queue_group_t
785queue_group_create_escope(
const char *name,
const em_core_mask_t *mask,
787 em_queue_group_t requested_queue_group,
791 em_queue_group_t queue_group;
793 odp_schedule_group_t odp_sched_group;
794 odp_thrmask_t zero_thrmask;
800 odp_thrmask_zero(&zero_thrmask);
808 queue_group = queue_group_alloc(requested_queue_group);
809 qgrp_elem = queue_group_elem_get(queue_group);
810 if (unlikely(qgrp_elem == NULL)) {
812 "Queue group alloc failed!");
818 odp_sched_group = create_odp_schedule_group(name, &zero_thrmask);
819 if (unlikely(odp_sched_group == ODP_SCHED_GROUP_INVALID)) {
820 queue_group_free(queue_group);
822 "ODP sched group creation for EM queue group (\"%s\") failed!",
835 odp_rwlock_read_lock(&core_map->
rwlock);
837 stat = queue_group_check_mask(mask);
838 if (unlikely(stat !=
EM_OK)) {
839 odp_rwlock_read_unlock(&core_map->
rwlock);
840 odp_schedule_group_destroy(odp_sched_group);
841 queue_group_free(queue_group);
844 char mstr[ODP_CPUMASK_STR_SIZE];
848 "Invalid mask given:%s", mstr);
855 odp_ticketlock_lock(&qgrp_elem->
lock);
861 odp_atomic_init_u32(&qgrp_elem->
num_queues, 0);
866 q_grp_add_core(qgrp_elem);
870 if (escope == EM_ESCOPE_QUEUE_GROUP_CREATE_SYNC)
871 q_grp_create_sync_done(qgrp_elem, mask);
873 q_grp_create_done(qgrp_elem, mask);
875 odp_ticketlock_unlock(&qgrp_elem->
lock);
876 odp_rwlock_read_unlock(&core_map->
rwlock);
879 if (unlikely(stat !=
EM_OK))
885 odp_ticketlock_unlock(&qgrp_elem->
lock);
887 stat = send_qgrp_addrem_reqs(qgrp_elem, mask, &add_mask, &rem_zero_mask,
888 num_notif, notif_tbl, escope);
890 odp_rwlock_read_unlock(&core_map->
rwlock);
892 if (unlikely(stat !=
EM_OK))
905 em_queue_group_t requested_queue_group)
907 return queue_group_create_escope(name, mask, num_notif, notif_tbl,
908 requested_queue_group,
909 EM_ESCOPE_QUEUE_GROUP_CREATE);
919 em_queue_group_t requested_queue_group)
921 return queue_group_create_escope(name, mask, 0, NULL,
922 requested_queue_group,
923 EM_ESCOPE_QUEUE_GROUP_CREATE_SYNC);
949 const char **err_str)
951 if (unlikely(!queue_group_allocated(qgrp_elem))) {
952 *err_str =
"Queue group not allocated";
956 *err_str =
"Contending queue group delete ongoing";
959 if (unlikely(is_delete && !list_is_empty(&qgrp_elem->
queue_list))) {
960 *err_str =
"Queue group contains queues, cannot delete group";
1008static void addrem_events_free(em_event_t add_events[],
int add_count,
1009 em_event_t rem_events[],
int rem_count)
1011 for (
int i = 0; i < add_count; i++) {
1015 for (
int i = 0; i < rem_count; i++) {
1031static em_status_t send_addrem_events(em_event_t addrem_events[],
int count,
1033 em_event_group_t event_group)
1035 const int first_qidx = queue_id2idx(
em_shm->queue_tbl.first_internal_queue_id);
1039 odp_thrmask_t thr_mask;
1047 mask_em2odp__rwlocked(mask, &thr_mask);
1049 thr = odp_thrmask_first(&thr_mask);
1050 while (thr >= 0 && ev_idx < count) {
1056 queue_idx2hdl(first_qidx + thr),
1058 if (unlikely(err !=
EM_OK))
1063 thr = odp_thrmask_next(&thr_mask, thr);
1072static int create_addrem_events(em_event_t addrem_events[],
int count,
1073 uint64_t ev_id, em_queue_group_t queue_group)
1077 if (unlikely(count < 1))
1087 i_event->
id = ev_id;
1088 i_event->
q_grp.queue_group = queue_group;
1090 for (
int i = 1; i < count; i++) {
1105 void (**f_done_callback)(
void *arg_ptr) ,
1106 bool *sync_operation )
1108 *sync_operation =
false;
1111 case EM_ESCOPE_QUEUE_GROUP_CREATE:
1112 *f_done_callback = q_grp_create_done_callback;
1114 case EM_ESCOPE_QUEUE_GROUP_CREATE_SYNC:
1115 *f_done_callback = q_grp_create_sync_done_callback;
1116 *sync_operation =
true;
1118 case EM_ESCOPE_QUEUE_GROUP_MODIFY:
1119 *f_done_callback = q_grp_modify_done_callback;
1121 case EM_ESCOPE_QUEUE_GROUP_MODIFY_SYNC:
1122 *f_done_callback = q_grp_modify_sync_done_callback;
1123 *sync_operation =
true;
1125 case EM_ESCOPE_QUEUE_GROUP_DELETE:
1126 *f_done_callback = q_grp_delete_done_callback;
1128 case EM_ESCOPE_QUEUE_GROUP_DELETE_SYNC:
1129 *f_done_callback = q_grp_delete_sync_done_callback;
1130 *sync_operation =
true;
1133 *f_done_callback = NULL;
1151 em_event_t callback_args_event =
1162 void (*f_done_callback)(
void *arg_ptr);
1163 void *f_done_arg_ptr = callback_args_event;
1164 bool sync_operation =
false;
1166 int ret = set_qgrp_done_func(escope, &f_done_callback,
1168 if (unlikely(ret)) {
1173 const em_queue_group_t queue_group = qgrp_elem->
queue_group;
1176 const int addrem_count = add_count + rem_count;
1177 em_event_t add_events[add_count];
1178 em_event_t rem_events[rem_count];
1179 em_event_group_t event_group;
1186 callback_args->qgrp_elem = qgrp_elem;
1195 f_done_callback, f_done_arg_ptr,
1196 num_notif, notif_tbl,
1203 for (
int i = 0; i < add_count; i++)
1205 for (
int i = 0; i < rem_count; i++)
1210 cnt = create_addrem_events(add_events , add_count,
1211 QUEUE_GROUP_ADD_REQ, queue_group);
1212 if (unlikely(cnt != add_count))
1213 goto err_free_resources;
1217 cnt = create_addrem_events(rem_events , rem_count,
1218 QUEUE_GROUP_REM_REQ, queue_group);
1219 if (unlikely(cnt != rem_count))
1220 goto err_free_resources;
1226 err = send_addrem_events(rem_events, rem_count, rem_mask, event_group);
1227 if (unlikely(err !=
EM_OK))
1228 goto err_free_resources;
1232 err = send_addrem_events(add_events, add_count, add_mask, event_group);
1234 if (unlikely(err !=
EM_OK))
1235 goto err_free_resources;
1240 addrem_events_free(add_events, add_count,
1241 rem_events, rem_count);
1265 const em_queue_group_t queue_group = qgrp_elem->
queue_group;
1267 const char *err_str =
"";
1268 const em_escope_t escope = is_delete ? EM_ESCOPE_QUEUE_GROUP_DELETE :
1269 EM_ESCOPE_QUEUE_GROUP_MODIFY;
1280 odp_rwlock_read_lock(&core_map->
rwlock);
1282 err = queue_group_check_mask(new_mask);
1283 if (unlikely(err !=
EM_OK)) {
1284 odp_rwlock_read_unlock(&core_map->
rwlock);
1287 char mstr[ODP_CPUMASK_STR_SIZE];
1291 "Queue group:%" PRI_QGRP ", invalid mask given:%s",
1295 odp_ticketlock_lock(&qgrp_elem->
lock);
1298 err = check_qgrp_state(qgrp_elem, is_delete, &err_str);
1299 if (unlikely(err !=
EM_OK)) {
1300 odp_ticketlock_unlock(&qgrp_elem->
lock);
1301 odp_rwlock_read_unlock(&core_map->
rwlock);
1315 int adds = count_qgrp_adds(&old_mask, new_mask, &add_mask );
1316 int rems = count_qgrp_rems(&old_mask, new_mask, &rem_mask );
1326 q_grp_add_core(qgrp_elem);
1336 q_grp_delete_done(qgrp_elem, new_mask);
1338 q_grp_modify_done(qgrp_elem, new_mask);
1340 odp_ticketlock_unlock(&qgrp_elem->
lock);
1341 odp_rwlock_read_unlock(&core_map->
rwlock);
1345 "notif sending failed");
1353 odp_ticketlock_unlock(&qgrp_elem->
lock);
1361 err = send_qgrp_addrem_reqs(qgrp_elem, new_mask, &add_mask, &rem_mask,
1362 num_notif, notif_tbl, escope);
1364 odp_rwlock_read_unlock(&core_map->
rwlock);
1367 "qgrp rem req(s) sending failed");
1386 const em_queue_group_t queue_group = qgrp_elem->
queue_group;
1388 const char *err_str =
"";
1389 const em_escope_t escope = is_delete ? EM_ESCOPE_QUEUE_GROUP_DELETE_SYNC
1390 : EM_ESCOPE_QUEUE_GROUP_MODIFY_SYNC;
1401 odp_rwlock_read_lock(&core_map->
rwlock);
1403 err = queue_group_check_mask(new_mask);
1404 if (unlikely(err !=
EM_OK)) {
1405 odp_rwlock_read_unlock(&core_map->
rwlock);
1408 char mstr[ODP_CPUMASK_STR_SIZE];
1412 "Queue group:%" PRI_QGRP ", invalid core mask given:%s",
1419 odp_ticketlock_lock(&qgrp_elem->
lock);
1422 err = check_qgrp_state(qgrp_elem, is_delete, &err_str);
1423 if (unlikely(err !=
EM_OK)) {
1424 odp_ticketlock_unlock(&qgrp_elem->
lock);
1425 goto queue_group_modify_sync_error;
1438 q_grp_delete_done(qgrp_elem, new_mask);
1440 odp_ticketlock_unlock(&qgrp_elem->
lock);
1443 goto queue_group_modify_sync_error;
1453 int adds = count_qgrp_adds(&old_mask, new_mask, &add_mask );
1454 int rems = count_qgrp_rems(&old_mask, new_mask, &rem_mask );
1463 q_grp_add_core(qgrp_elem);
1468 q_grp_rem_core(qgrp_elem);
1472 if (adds == 0 && rems == 0) {
1474 q_grp_delete_done(qgrp_elem, new_mask);
1476 q_grp_modify_done(qgrp_elem, new_mask);
1478 odp_ticketlock_unlock(&qgrp_elem->
lock);
1480 goto queue_group_modify_sync_error;
1483 odp_ticketlock_unlock(&qgrp_elem->
lock);
1491 err = send_qgrp_addrem_reqs(qgrp_elem, new_mask, &add_mask, &rem_mask,
1494 odp_rwlock_read_unlock(&core_map->
rwlock);
1496 if (unlikely(err !=
EM_OK)) {
1499 goto queue_group_modify_sync_error;
1513queue_group_modify_sync_error:
1514 odp_rwlock_read_unlock(&core_map->
rwlock);
1517 "Failure: Modify sync QGrp:%" PRI_QGRP ":%s",
1518 queue_group, err_str);
1530 int odp_thr = odp_thread_id();
1531 odp_thrmask_t odp_joinmask;
1533 odp_thrmask_zero(&odp_joinmask);
1534 odp_thrmask_set(&odp_joinmask, odp_thr);
1538 if (unlikely(ret)) {
1540 em_queue_group_t queue_group = qgrp_elem->
queue_group;
1545 "QGrp ADD core%02d: odp_schedule_group_join(thr:%d):%d\n"
1546 "QueueGroup:%" PRI_QGRP " core-mask:%s",
1547 em_core_id(), odp_thr, ret, queue_group, mask_str);
1559 int odp_thr = odp_thread_id();
1560 odp_thrmask_t odp_leavemask;
1562 odp_thrmask_zero(&odp_leavemask);
1563 odp_thrmask_set(&odp_leavemask, odp_thr);
1567 if (unlikely(ret)) {
1569 em_queue_group_t queue_group = qgrp_elem->
queue_group;
1574 "QGrp REM core%02d: odp_schedule_group_leave(thr:%d):%d\n"
1575 "QueueGroup:%" PRI_QGRP " core-mask:%s",
1576 em_core_id(), odp_thr, ret, queue_group, mask_str);
1582 em_queue_group_t qgrp = i_ev->
q_grp.queue_group;
1585 if (unlikely(!qgrp_elem))
1588 odp_ticketlock_lock(&qgrp_elem->
lock);
1589 q_grp_add_core(qgrp_elem);
1590 odp_ticketlock_unlock(&qgrp_elem->
lock);
1595 em_queue_group_t qgrp = i_ev->
q_grp.queue_group;
1598 if (unlikely(!qgrp_elem))
1601 odp_ticketlock_lock(&qgrp_elem->
lock);
1602 q_grp_rem_core(qgrp_elem);
1603 odp_ticketlock_unlock(&qgrp_elem->
lock);
1610static void q_grp_create_done_callback(
void *arg_ptr)
1612 em_event_t
event = (em_event_t)arg_ptr;
1616 odp_ticketlock_lock(&qgrp_elem->
lock);
1617 q_grp_create_done(qgrp_elem, &args->new_mask);
1618 odp_ticketlock_unlock(&qgrp_elem->
lock);
1627static void q_grp_create_sync_done_callback(
void *arg_ptr)
1629 em_event_t
event = (em_event_t)arg_ptr;
1633 odp_ticketlock_lock(&qgrp_elem->
lock);
1634 q_grp_create_sync_done(qgrp_elem, &args->new_mask);
1635 odp_ticketlock_unlock(&qgrp_elem->
lock);
1658static void q_grp_modify_done_callback(
void *arg_ptr)
1660 em_event_t
event = (em_event_t)arg_ptr;
1664 odp_ticketlock_lock(&qgrp_elem->
lock);
1665 q_grp_modify_done(qgrp_elem, &args->new_mask);
1666 odp_ticketlock_unlock(&qgrp_elem->
lock);
1675static void q_grp_modify_sync_done_callback(
void *arg_ptr)
1679 q_grp_modify_done_callback(arg_ptr);
1696static void q_grp_delete_done_callback(
void *arg_ptr)
1698 em_event_t
event = (em_event_t)arg_ptr;
1702 odp_ticketlock_lock(&qgrp_elem->
lock);
1703 q_grp_delete_done(qgrp_elem, &args->new_mask);
1704 odp_ticketlock_unlock(&qgrp_elem->
lock);
1713static void q_grp_delete_sync_done_callback(
void *arg_ptr)
1717 q_grp_delete_done_callback(arg_ptr);
1726 const unsigned int num_queues = odp_atomic_load_u32(&qgrp_elem->
num_queues);
1727 const em_queue_group_t queue_group = qgrp_elem->
queue_group;
1735 "Delete QGrp:%" PRI_QGRP " mask not zero:%s",
1746 "Delete QGrp:%" PRI_QGRP ", masks modified during delete:%s vs. %s",
1747 queue_group, mstr1, mstr2);
1750 if (unlikely(!list_is_empty(&qgrp_elem->
queue_list) || num_queues))
1752 "Delete QGrp:%" PRI_QGRP ", contains %u queues, cannot delete!",
1753 queue_group, num_queues);
1757 if (unlikely(ret != 0))
1759 "Delete QGrp:%" PRI_QGRP ", ODP sched grp destroy fails:%d",
1772 odp_ticketlock_lock(&queue_group_elem->
lock);
1774 odp_atomic_inc_u32(&queue_group_elem->
num_queues);
1775 odp_ticketlock_unlock(&queue_group_elem->
lock);
1781 odp_ticketlock_lock(&queue_group_elem->
lock);
1782 if (!list_is_empty(&queue_group_elem->
queue_list)) {
1784 odp_atomic_dec_u32(&queue_group_elem->
num_queues);
1786 odp_ticketlock_unlock(&queue_group_elem->
lock);
1789unsigned int queue_group_count(
void)
1794#define QGRP_INFO_HDR_STR \
1795"EM Queue group(s):%2u\n" \
1796"ID Name EM-mask Cpumask " \
1797" ODP-mask Q-num\n" \
1798"------------------------------------------------------------------------------" \
1799"------------------------------\n" \
1803#define QGRP_INFO_LEN (108 + 1 )
1804#define QGRP_INFO_FMT "%-10" PRI_QGRP "%-32s%-20s%-20s%-20s%-5d\n"
1806static void queue_group_info_str(em_queue_group_t queue_group,
1807 char qgrp_info_str[])
1810 odp_thrmask_t odp_thrmask;
1814 char odp_thrmask_str[ODP_THRMASK_STR_SIZE];
1822 if (unlikely(!qgrp_elem || !queue_group_allocated(qgrp_elem)))
1823 goto info_print_err;
1827 if (unlikely(err !=
EM_OK))
1828 goto info_print_err;
1835 goto info_print_err;
1836 ret = odp_thrmask_to_str(&odp_thrmask, odp_thrmask_str,
1837 sizeof(odp_thrmask_str));
1838 if (unlikely(ret <= 0))
1839 goto info_print_err;
1840 odp_thrmask_str[ret - 1] =
'\0';
1847 len = snprintf(qgrp_info_str, QGRP_INFO_LEN, QGRP_INFO_FMT,
1848 queue_group, qgrp_name, em_mask_str,
1849 phys_mask_str, odp_thrmask_str,
1850 odp_atomic_load_u32(&qgrp_elem->
num_queues));
1852 qgrp_info_str[len] =
'\0';
1856 len = snprintf(qgrp_info_str, QGRP_INFO_LEN, QGRP_INFO_FMT,
1857 queue_group,
"err:n/a",
"n/a",
"n/a",
"n/a", 0);
1858 qgrp_info_str[len] =
'\0';
1861void queue_group_info_print_all(
void)
1863 em_queue_group_t qgrp;
1864 unsigned int qgrp_num;
1865 char single_qgrp_info_str[QGRP_INFO_LEN];
1881 const int all_qgrp_info_str_len = (qgrp_num + 10) * QGRP_INFO_LEN + 1;
1882 char all_qgrp_info_str[all_qgrp_info_str_len];
1885 queue_group_info_str(qgrp, single_qgrp_info_str);
1887 n_print = snprintf(all_qgrp_info_str + len,
1888 all_qgrp_info_str_len - len,
1889 "%s", single_qgrp_info_str);
1892 if (n_print >= all_qgrp_info_str_len - len)
1901 EM_PRINT(
"No EM queue group!\n");
1909 all_qgrp_info_str[len] =
'\0';
1910 EM_PRINT(QGRP_INFO_HDR_STR, qgrp_num, all_qgrp_info_str);
1913#define QGRO_QUEUE_INFO_HDR_STR \
1914"Queue group %" PRI_QGRP "(%s) has %d queue(s):\n\n" \
1915"Id Name Priority Type State Ctx\n" \
1916"--------------------------------------------------------------------------\n" \
1920#define QGRP_Q_LEN 75
1921#define QGRP_Q_INFO_FMT "%-10" PRI_QUEUE "%-32s%-10d%-10s%-9s%-3c\n"
1923void queue_group_queues_print(em_queue_group_t qgrp)
1926 em_queue_t qgrp_queue;
1935 if (unlikely(!qgrp_elem || !queue_group_allocated(qgrp_elem))) {
1936 EM_PRINT(
"Queue group %" PRI_QGRP " is not created!\n", qgrp);
1952 const int q_info_len = (q_num + 10) * QGRP_Q_LEN + 1;
1953 char q_info_str[q_info_len];
1956 q_elem = queue_elem_get(qgrp_queue);
1958 if (unlikely(q_elem == NULL || !queue_allocated(q_elem))) {
1965 n_print = snprintf(q_info_str + len, q_info_len - len,
1966 QGRP_Q_INFO_FMT, qgrp_queue, q_name,
1968 queue_type_str(q_elem->
type),
1969 queue_state_str(q_elem->
state),
1973 if (n_print >= q_info_len - len)
1982 EM_PRINT(
"Queue group %" PRI_QGRP "(%s) has no queue!\n",
1991 q_info_str[len] =
'\0';
1992 EM_PRINT(QGRO_QUEUE_INFO_HDR_STR, qgrp, qgrp_name, q_num, q_info_str);
#define INTERNAL_ERROR(error, escope, fmt,...)
#define RETURN_ERROR_IF(cond, error, escope, fmt,...)
em_status_t send_ctrl_queue(em_event_t event, em_queue_t queue, em_event_group_t event_group)
struct event_hdr event_hdr_t
em_event_group_t internal_done_w_notif_req(int event_group_count, void(*f_done_callback)(void *arg_ptr), void *f_done_arg_ptr, int num_notif, const em_notif_t notif_tbl[], bool sync_operation)
Helper func: Allocate & set up the internal 'done' event with function callbacks and notification eve...
void poll_unsched_ctrl_queue(void)
Poll EM's internal unscheduled control queues during dispatch.
void evgrp_abort_delete(em_event_group_t event_group)
internal_done_w_notif_req() 'companion' to abort and delete the event group created by the mentioned ...
em_status_t send_notifs(const int num_notif, const em_notif_t notif_tbl[])
Helper func to send notifications events.
ENV_LOCAL em_locm_t em_locm
#define EM_QUEUE_NAME_LEN
#define EM_MAX_QUEUE_GROUPS
#define EM_QUEUE_GROUP_NAME_LEN
#define EM_QUEUE_GROUP_DEFAULT_NAME
#define EM_QUEUE_GROUP_DEFAULT
int em_core_mask_equal(const em_core_mask_t *mask1, const em_core_mask_t *mask2)
int em_core_mask_count(const em_core_mask_t *mask)
void em_core_mask_tostr(char *mask_str, int len, const em_core_mask_t *mask)
int em_core_mask_iszero(const em_core_mask_t *mask)
void em_core_mask_copy(em_core_mask_t *dst, const em_core_mask_t *src)
void em_core_mask_set(int core, em_core_mask_t *mask)
void em_core_mask_clr(int core, em_core_mask_t *mask)
int em_core_mask_isset(int core, const em_core_mask_t *mask)
void em_core_mask_and(em_core_mask_t *dst, const em_core_mask_t *src1, const em_core_mask_t *src2)
#define EM_CORE_MASK_STRLEN
void em_core_mask_zero(em_core_mask_t *mask)
void em_core_mask_xor(em_core_mask_t *dst, const em_core_mask_t *src1, const em_core_mask_t *src2)
void em_core_mask_physical(em_core_mask_t *phys, const em_core_mask_t *logic)
#define EM_QUEUE_GROUP_UNDEF
#define EM_EVENT_GROUP_UNDEF
@ EM_ERR_OPERATION_FAILED
em_event_t em_event_clone(em_event_t event, em_pool_t pool)
Clone an event.
em_event_t em_alloc(uint32_t size, em_event_type_t type, em_pool_t pool)
void em_free(em_event_t event)
void * em_event_pointer(em_event_t event)
em_queue_group_t em_queue_group_find(const char *name)
em_queue_group_t em_queue_group_first(unsigned int *num)
size_t em_queue_group_name(em_queue_group_t queue_group, char *name, size_t maxlen)
em_queue_group_t em_queue_group_next(void)
em_queue_t em_queue_group_queue_first(unsigned int *num, em_queue_group_t queue_group)
em_queue_t em_queue_group_queue_next(void)
em_status_t em_queue_group_mask(em_queue_group_t queue_group, em_core_mask_t *mask)
em_core_mask_t logic_mask
odp_atomic_u32_t queue_group_count
objpool_elem_t queue_group_pool_elem
em_queue_group_t queue_group
odp_atomic_u32_t num_queues
list_node_t qgrp_list_node
odp_schedule_group_t odp_sched_group
queue_group_elem_t queue_group_elem[EM_MAX_QUEUE_GROUPS]
struct internal_event_t::@50 q_grp