@@ -36,6 +36,8 @@ static const stress_help_t help[] = {
3636 { NULL , NULL , NULL }
3737};
3838
39+ #define IOCTL_TIMEOUT_US (100000)
40+
3941/* Index order to stress_bad_ioctl_methods */
4042#define STRESS_BAD_IOCTL_CMD_INC (0)
4143#define STRESS_BAD_IOCTL_CMD_RANDOM (1)
@@ -85,6 +87,7 @@ static sigset_t set;
8587static void * node_lock ;
8688static uint32_t mixup ;
8789static dev_ioctl_info_t * dev_ioctl_info_head ;
90+ static size_t dev_ioctl_info_count ;
8891static volatile dev_ioctl_info_t * dev_ioctl_node ;
8992
9093typedef struct stress_bad_ioctl_func {
@@ -95,6 +98,24 @@ typedef struct stress_bad_ioctl_func {
9598
9699static sigjmp_buf jmp_env ;
97100
101+ static void stress_bad_ioctl_itimer_set (const suseconds_t usec )
102+ {
103+ #if defined(HAVE_SETITIMER ) && \
104+ defined(SIGPROF )
105+ struct itimerval timer ;
106+
107+ (void )shim_memset (& timer , 0 , sizeof (timer ));
108+ timer .it_value .tv_sec = usec / 1000000 ;
109+ timer .it_value .tv_usec = usec % 1000000 ;
110+ timer .it_interval .tv_sec = timer .it_value .tv_sec ;
111+ timer .it_interval .tv_usec = timer .it_value .tv_usec ;
112+
113+ (void )setitimer (ITIMER_PROF , & timer , NULL );
114+ #else
115+ (void )usec ;
116+ #endif
117+ }
118+
98119/*
99120 * stress_bad_ioctl_dev_new()
100121 * add a new ioctl device path to tree
@@ -122,6 +143,7 @@ static dev_ioctl_info_t *stress_bad_ioctl_dev_new(
122143 }
123144 node -> ignore = false;
124145 node -> ioctl_state = stress_mwc16 ();
146+ dev_ioctl_info_count ++ ;
125147
126148 * head = node ;
127149 return node ;
@@ -223,9 +245,11 @@ static void stress_bad_ioctl_dev_dir(
223245 stress_fs_dirent_list_free (dlist , n );
224246}
225247
226- static void NORETURN MLOCKED_TEXT stress_segv_handler (int signum )
248+ static void MLOCKED_TEXT stress_sig_handler (int signum )
227249{
228- stress_signal_siglongjmp (signum , jmp_env , 1 );
250+ stress_bad_ioctl_itimer_set (0 );
251+ if (signum == SIGALRM )
252+ stress_signal_siglongjmp (signum , jmp_env , 1 );
229253}
230254
231255/*
@@ -237,7 +261,7 @@ static inline void stress_bad_ioctl_rw(
237261 const bool is_pthread ,
238262 const size_t thread_index )
239263{
240- const double threshold = 0.25 ;
264+ const double threshold = IOCTL_TIMEOUT_US / 1000000.0 ;
241265 const size_t page_size = args -> page_size ;
242266 uint64_t * buf ;
243267 uint64_t * buf_page1 ;
@@ -291,6 +315,8 @@ static inline void stress_bad_ioctl_rw(
291315 uint64_t rnd = stress_mwc32 ();
292316 volatile dev_ioctl_info_t * node ;
293317
318+ stress_bad_ioctl_itimer_set (0 );
319+
294320 ret = stress_lock_acquire (node_lock );
295321 if (ret )
296322 break ;
@@ -302,8 +328,6 @@ static inline void stress_bad_ioctl_rw(
302328 type = (node -> ioctl_state >> 8 ) & 0xff ;
303329 nr = (node -> ioctl_state ) & 0xff ;
304330
305- t_start = stress_time_now ();
306-
307331 for (ptr = (uint32_t * )buf ; ptr < buf_end ; ptr ++ ) {
308332 * ptr ^= rnd ;
309333 }
@@ -319,121 +343,161 @@ static inline void stress_bad_ioctl_rw(
319343
320344 (void )shim_memset (buf , 0 , page_size );
321345
346+ t_start = stress_time_now ();
347+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
322348 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint64_t ), buf64 ));
323349 if (stress_time_now () - t_start > threshold ) {
324350 (void )close (fd );
325351 break ;
326352 }
327353
354+ t_start = stress_time_now ();
355+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
328356 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint32_t ), buf32 ));
329357 if (stress_time_now () - t_start > threshold ) {
330358 (void )close (fd );
331359 break ;
332360 }
333361
362+ t_start = stress_time_now ();
363+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
334364 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint16_t ), buf16 ));
335365 if (stress_time_now () - t_start > threshold ) {
336366 (void )close (fd );
337367 break ;
338368 }
339369
370+ t_start = stress_time_now ();
371+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
340372 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint8_t ), buf8 ));
341373 if (stress_time_now () - t_start > threshold ) {
342374 (void )close (fd );
343375 break ;
344376 }
345377
378+ t_start = stress_time_now ();
379+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
346380 VOID_RET (int , ioctl (fd , _IOR (type , nr , stress_4k_page_t ), buf ));
347381 if (stress_time_now () - t_start > threshold ) {
348382 (void )close (fd );
349383 break ;
350384 }
351385
386+ t_start = stress_time_now ();
387+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
352388 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint64_t ), NULL ));
353389 if (stress_time_now () - t_start > threshold ) {
354390 (void )close (fd );
355391 break ;
356392 }
357393
394+ t_start = stress_time_now ();
395+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
358396 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint32_t ), NULL ));
359397 if (stress_time_now () - t_start > threshold ) {
360398 (void )close (fd );
361399 break ;
362400 }
363401
402+ t_start = stress_time_now ();
403+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
364404 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint16_t ), NULL ));
365405 if (stress_time_now () - t_start > threshold ) {
366406 (void )close (fd );
367407 break ;
368408 }
369409
410+ t_start = stress_time_now ();
411+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
370412 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint8_t ), NULL ));
371413 if (stress_time_now () - t_start > threshold ) {
372414 (void )close (fd );
373415 break ;
374416 }
375417
418+ t_start = stress_time_now ();
419+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
376420 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint64_t ), args -> mapped -> page_none ));
377421 if (stress_time_now () - t_start > threshold ) {
378422 (void )close (fd );
379423 break ;
380424 }
381425
426+ t_start = stress_time_now ();
427+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
382428 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint32_t ), args -> mapped -> page_none ));
383429 if (stress_time_now () - t_start > threshold ) {
384430 (void )close (fd );
385431 break ;
386432 }
387433
434+ t_start = stress_time_now ();
435+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
388436 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint16_t ), args -> mapped -> page_none ));
389437 if (stress_time_now () - t_start > threshold ) {
390438 (void )close (fd );
391439 break ;
392440 }
393441
442+ t_start = stress_time_now ();
443+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
394444 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint8_t ), args -> mapped -> page_none ));
395445 if (stress_time_now () - t_start > threshold ) {
396446 (void )close (fd );
397447 break ;
398448 }
399449
450+ t_start = stress_time_now ();
451+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
400452 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint32_t ), args -> mapped -> page_ro ));
401453 if (stress_time_now () - t_start > threshold ) {
402454 (void )close (fd );
403455 break ;
404456 }
405457
458+ t_start = stress_time_now ();
459+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
406460 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint16_t ), args -> mapped -> page_ro ));
407461 if (stress_time_now () - t_start > threshold ) {
408462 (void )close (fd );
409463 break ;
410464 }
411465
466+ t_start = stress_time_now ();
467+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
412468 VOID_RET (int , ioctl (fd , _IOR (type , nr , uint8_t ), args -> mapped -> page_ro ));
413469 if (stress_time_now () - t_start > threshold ) {
414470 (void )close (fd );
415471 break ;
416472 }
417473
418474#if defined(_IOW )
475+ t_start = stress_time_now ();
476+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
419477 VOID_RET (int , ioctl (fd , _IOW (type , nr , uint64_t ), args -> mapped -> page_none ));
420478 if (stress_time_now () - t_start > threshold ) {
421479 (void )close (fd );
422480 break ;
423481 }
424482
483+ t_start = stress_time_now ();
484+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
425485 VOID_RET (int , ioctl (fd , _IOW (type , nr , uint32_t ), args -> mapped -> page_none ));
426486 if (stress_time_now () - t_start > threshold ) {
427487 (void )close (fd );
428488 break ;
429489 }
430490
491+ t_start = stress_time_now ();
492+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
431493 VOID_RET (int , ioctl (fd , _IOW (type , nr , uint16_t ), args -> mapped -> page_none ));
432494 if (stress_time_now () - t_start > threshold ) {
433495 (void )close (fd );
434496 break ;
435497 }
436498
499+ t_start = stress_time_now ();
500+ stress_bad_ioctl_itimer_set (IOCTL_TIMEOUT_US );
437501 VOID_RET (int , ioctl (fd , _IOW (type , nr , uint8_t ), args -> mapped -> page_none ));
438502 if (stress_time_now () - t_start > threshold ) {
439503 (void )close (fd );
@@ -442,6 +506,8 @@ static inline void stress_bad_ioctl_rw(
442506#endif
443507
444508 (void )close (fd );
509+ stress_bad_ioctl_itimer_set (0 );
510+
445511 if (thread_index < MAX_DEV_THREADS ) {
446512 ret = stress_lock_acquire (node_lock );
447513 if (ret )
@@ -451,6 +517,7 @@ static inline void stress_bad_ioctl_rw(
451517 }
452518 } while (is_pthread );
453519
520+ stress_bad_ioctl_itimer_set (0 );
454521 (void )munmap ((void * )buf , page_size );
455522}
456523
@@ -574,13 +641,17 @@ static int stress_bad_ioctl(stress_args_t *args)
574641
575642 node_lock = NULL ;
576643 dev_ioctl_info_head = NULL ;
644+ dev_ioctl_info_count = 0 ;
577645 dev_ioctl_node = NULL ;
578646
579647 (void )stress_setting_get ("bad-ioctl-method" , & bad_ioctl_method );
580648
581649 stress_bad_ioctl_dev_dir (args , "/dev" , 0 );
582650 dev_ioctl_node = dev_ioctl_info_head ;
583651
652+ if (stress_instance_zero (args ))
653+ pr_inf ("%s: %zu unique devices being exercised with ioctl calls\n" , args -> name , dev_ioctl_info_count );
654+
584655 stress_proc_state_set (args -> name , STRESS_STATE_SYNC_WAIT );
585656 stress_sync_start_wait (args );
586657 stress_proc_state_set (args -> name , STRESS_STATE_RUN );
@@ -622,14 +693,22 @@ static int stress_bad_ioctl(stress_args_t *args)
622693 uint32_t offset ;
623694
624695 stress_proc_state_set (args -> name , STRESS_STATE_RUN );
696+
697+ stress_bad_ioctl_itimer_set (0 );
698+
625699 ssjret = sigsetjmp (jmp_env , 1 );
626700 if (ssjret != 0 ) {
627701 pr_fail ("%s: caught an unexpected segmentation fault\n" , args -> name );
628702 _exit (EXIT_FAILURE );
629703 }
630704
631- if (stress_signal_handler (args -> name , SIGSEGV , stress_segv_handler , NULL ) < 0 )
705+ if (stress_signal_handler (args -> name , SIGSEGV , stress_sig_handler , NULL ) < 0 )
706+ _exit (EXIT_NO_RESOURCE );
707+ #if defined(HAVE_SETITIMER ) && \
708+ defined(SIGPROF )
709+ if (stress_signal_handler (args -> name , SIGPROF , stress_sig_handler , NULL ) < 0 )
632710 _exit (EXIT_NO_RESOURCE );
711+ #endif
633712
634713 stress_make_it_fail_set ();
635714 stress_parent_died_alarm ();
@@ -672,6 +751,7 @@ static int stress_bad_ioctl(stress_args_t *args)
672751 (void )pthread_join (threads [i ].pthread , NULL );
673752 }
674753 (void )stress_lock_destroy (node_lock );
754+
675755 _exit (EXIT_SUCCESS );
676756 }
677757 } while (stress_continue (args ));
0 commit comments