From mboxrd@z Thu Jan 1 00:00:00 1970 From: Cunming Liang Subject: [PATCH v2 15/15] timer: add support to non-EAL thread Date: Wed, 28 Jan 2015 14:59:25 +0800 Message-ID: <1422428365-5875-16-git-send-email-cunming.liang@intel.com> References: <1421914598-2747-1-git-send-email-cunming.liang@intel.com> <1422428365-5875-1-git-send-email-cunming.liang@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable To: dev-VfR2kkLFssw@public.gmane.org Return-path: In-Reply-To: <1422428365-5875-1-git-send-email-cunming.liang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces-VfR2kkLFssw@public.gmane.org Sender: "dev" Allow to setup timers only for EAL (lcore) threads (__lcore_id < MAX_LCOR= E_ID). E.g. =E2=80=93 dynamically created thread will be able to reset/stop time= r for lcore thread, but it will be not allowed to setup timer for itself or another non-lcore= thread. rte_timer_manage() for non-lcore thread would simply do nothing and retur= n straightway. Signed-off-by: Cunming Liang --- lib/librte_timer/rte_timer.c | 40 +++++++++++++++++++++++++++++++-------= -- lib/librte_timer/rte_timer.h | 2 +- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c index 269a992..601c159 100644 --- a/lib/librte_timer/rte_timer.c +++ b/lib/librte_timer/rte_timer.c @@ -79,9 +79,10 @@ static struct priv_timer priv_timer[RTE_MAX_LCORE]; =20 /* when debug is enabled, store some statistics */ #ifdef RTE_LIBRTE_TIMER_DEBUG -#define __TIMER_STAT_ADD(name, n) do { \ - unsigned __lcore_id =3D rte_lcore_id(); \ - priv_timer[__lcore_id].stats.name +=3D (n); \ +#define __TIMER_STAT_ADD(name, n) do { \ + unsigned __lcore_id =3D rte_lcore_id(); \ + if (__lcore_id < RTE_MAX_LCORE) \ + priv_timer[__lcore_id].stats.name +=3D (n); \ } while(0) #else #define __TIMER_STAT_ADD(name, n) do {} while(0) @@ -127,15 +128,26 @@ timer_set_config_state(struct rte_timer *tim, unsigned lcore_id; =20 lcore_id =3D rte_lcore_id(); + if (lcore_id >=3D RTE_MAX_LCORE) + lcore_id =3D LCORE_ID_ANY; =20 /* wait that the timer is in correct status before update, * and mark it as being configured */ while (success =3D=3D 0) { prev_status.u32 =3D tim->status.u32; =20 + /* + * prevent race condition of non-EAL threads + * to update the timer. When 'owner =3D=3D LCORE_ID_ANY', + * it means updated by a non-EAL thread. + */ + if (lcore_id =3D=3D (unsigned)LCORE_ID_ANY && + (uint16_t)lcore_id =3D=3D prev_status.owner) + return -1; + /* timer is running on another core, exit */ if (prev_status.state =3D=3D RTE_TIMER_RUNNING && - (unsigned)prev_status.owner !=3D lcore_id) + prev_status.owner !=3D (uint16_t)lcore_id) return -1; =20 /* timer is being configured on another core */ @@ -366,9 +378,13 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t ex= pire, =20 /* round robin for tim_lcore */ if (tim_lcore =3D=3D (unsigned)LCORE_ID_ANY) { - tim_lcore =3D rte_get_next_lcore(priv_timer[lcore_id].prev_lcore, - 0, 1); - priv_timer[lcore_id].prev_lcore =3D tim_lcore; + if (lcore_id < RTE_MAX_LCORE) { + tim_lcore =3D rte_get_next_lcore( + priv_timer[lcore_id].prev_lcore, + 0, 1); + priv_timer[lcore_id].prev_lcore =3D tim_lcore; + } else + tim_lcore =3D rte_get_next_lcore(LCORE_ID_ANY, 0, 1); } =20 /* wait that the timer is in correct status before update, @@ -378,7 +394,8 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t exp= ire, return -1; =20 __TIMER_STAT_ADD(reset, 1); - if (prev_status.state =3D=3D RTE_TIMER_RUNNING) { + if (prev_status.state =3D=3D RTE_TIMER_RUNNING && + lcore_id < RTE_MAX_LCORE) { priv_timer[lcore_id].updated =3D 1; } =20 @@ -455,7 +472,8 @@ rte_timer_stop(struct rte_timer *tim) return -1; =20 __TIMER_STAT_ADD(stop, 1); - if (prev_status.state =3D=3D RTE_TIMER_RUNNING) { + if (prev_status.state =3D=3D RTE_TIMER_RUNNING && + lcore_id < RTE_MAX_LCORE) { priv_timer[lcore_id].updated =3D 1; } =20 @@ -499,6 +517,10 @@ void rte_timer_manage(void) uint64_t cur_time; int i, ret; =20 + /* timer manager only runs on EAL thread */ + if (lcore_id >=3D RTE_MAX_LCORE) + return; + __TIMER_STAT_ADD(manage, 1); /* optimize for the case where per-cpu list is empty */ if (priv_timer[lcore_id].pending_head.sl_next[0] =3D=3D NULL) diff --git a/lib/librte_timer/rte_timer.h b/lib/librte_timer/rte_timer.h index 4907cf5..5c5df91 100644 --- a/lib/librte_timer/rte_timer.h +++ b/lib/librte_timer/rte_timer.h @@ -76,7 +76,7 @@ extern "C" { #define RTE_TIMER_RUNNING 2 /**< State: timer function is running. */ #define RTE_TIMER_CONFIG 3 /**< State: timer is being configured. */ =20 -#define RTE_TIMER_NO_OWNER -1 /**< Timer has no owner. */ +#define RTE_TIMER_NO_OWNER -2 /**< Timer has no owner. */ =20 /** * Timer type: Periodic or single (one-shot). --=20 1.8.1.4