@@ -3079,12 +3079,13 @@ static int method_endpoint_remove(sd_bus_message *call, void *data,
30793079 (MCTP_I2C_TSYM_MT1_MAX_US + 2 * MCTP_I2C_TSYM_MT3_MAX_US)
30803080#define MCTP_I2C_TSYM_MT2_MAX_MS MCTP_I2C_TSYM_MT4_MIN_US
30813081
3082- static int peer_endpoint_recover (sd_event_source * s , uint64_t usec ,
3082+ static int peer_endpoint_recover (sd_event_source * s , int timerfd , uint revents ,
30833083 void * userdata )
30843084{
30853085 struct peer * peer = userdata ;
30863086 struct ctx * ctx = peer -> ctx ;
30873087 const char * peer_path ;
3088+ uint64_t n_expireds ;
30883089 int rc ;
30893090
30903091 /*
@@ -3099,6 +3100,12 @@ static int peer_endpoint_recover(sd_event_source *s, uint64_t usec,
30993100
31003101 peer -> recovery .npolls -- ;
31013102
3103+ // flush the timerfd
3104+ rc = mctp_ops .timerfd .read (timerfd , & n_expireds );
3105+ if (rc < 0 ) {
3106+ goto reschedule ;
3107+ }
3108+
31023109 /*
31033110 * Test if we still have connectivity to the endpoint. If we do, we will get a
31043111 * response reporting the current EID. This is the test recommended by 8.17.6
@@ -3194,8 +3201,8 @@ static int peer_endpoint_recover(sd_event_source *s, uint64_t usec,
31943201
31953202reschedule :
31963203 if (peer -> recovery .npolls > 0 ) {
3197- rc = sd_event_source_set_time_relative ( peer -> recovery .source ,
3198- peer -> recovery . delay );
3204+ rc = mctp_ops . timerfd . settime ( timerfd , peer -> recovery .delay ,
3205+ NULL );
31993206 if (rc >= 0 ) {
32003207 rc = sd_event_source_set_enabled (peer -> recovery .source ,
32013208 SD_EVENT_ONESHOT );
@@ -3217,11 +3224,13 @@ static int method_endpoint_recover(sd_bus_message *call, void *data,
32173224 struct peer * peer ;
32183225 bool previously ;
32193226 struct ctx * ctx ;
3227+ int timerfd ;
32203228 int rc ;
32213229
32223230 peer = data ;
32233231 ctx = peer -> ctx ;
32243232 previously = peer -> degraded ;
3233+ timerfd = -1 ;
32253234
32263235 if (!previously ) {
32273236 assert (!peer -> recovery .delay );
@@ -3230,13 +3239,38 @@ static int method_endpoint_recover(sd_bus_message *call, void *data,
32303239 peer -> recovery .npolls = MCTP_I2C_TSYM_MN1_MIN + 1 ;
32313240 peer -> recovery .delay =
32323241 (MCTP_I2C_TSYM_TRECLAIM_MIN_US / 2 ) - ctx -> mctp_timeout ;
3233- rc = sd_event_add_time_relative (
3234- ctx -> event , & peer -> recovery .source , CLOCK_MONOTONIC , 0 ,
3235- ctx -> mctp_timeout , peer_endpoint_recover , peer );
3242+
3243+ timerfd = mctp_ops .timerfd .create ();
3244+ if (timerfd < 0 ) {
3245+ rc = - errno ;
3246+ goto out ;
3247+ }
3248+
3249+ rc = mctp_ops .timerfd .settime (timerfd , ctx -> mctp_timeout , NULL );
3250+ if (rc < 0 ) {
3251+ goto out ;
3252+ }
3253+
3254+ rc = sd_event_add_io (ctx -> event , & peer -> recovery .source ,
3255+ timerfd , EPOLLIN , peer_endpoint_recover ,
3256+ peer );
3257+ if (rc < 0 ) {
3258+ goto out ;
3259+ }
3260+
3261+ rc = sd_event_source_set_enabled (peer -> recovery .source ,
3262+ SD_EVENT_ONESHOT );
32363263 if (rc < 0 ) {
32373264 goto out ;
32383265 }
32393266
3267+ rc = sd_event_source_set_io_fd_own (peer -> recovery .source , true);
3268+ if (rc < 0 ) {
3269+ goto out ;
3270+ }
3271+ // prevent double close, now that sd_event_source own the fd
3272+ timerfd = -1 ;
3273+
32403274 peer -> degraded = true;
32413275
32423276 rc = sd_bus_emit_properties_changed (
@@ -3253,12 +3287,8 @@ static int method_endpoint_recover(sd_bus_message *call, void *data,
32533287
32543288out :
32553289 if (rc < 0 && !previously ) {
3256- if (peer -> degraded ) {
3257- /* Cleanup the timer if it was setup successfully. */
3258- sd_event_source_set_enabled (peer -> recovery .source ,
3259- SD_EVENT_OFF );
3260- sd_event_source_unref (peer -> recovery .source );
3261- }
3290+ sd_event_source_disable_unref (peer -> recovery .source );
3291+ close (timerfd );
32623292 peer -> degraded = previously ;
32633293 peer -> recovery .delay = 0 ;
32643294 peer -> recovery .source = NULL ;
0 commit comments