Print this page
3830 SIGQUEUE_MAX's limit of 32 is too low
Reviewed by: Cedric Blancher <cedric.blancher@gmail.com>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Reviewed by: Irek Szczesniak <iszczesniak@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/os/sig.c
          +++ new/usr/src/uts/common/os/sig.c
↓ open down ↓ 2363 lines elided ↑ open up ↑
2364 2364                  case SI_QUEUE:
2365 2365                  case SI_TIMER:
2366 2366                  case SI_ASYNCIO:
2367 2367                  case SI_MESGQ:
2368 2368                          return (1);
2369 2369                  }
2370 2370          }
2371 2371          return (0);
2372 2372  }
2373 2373  
2374      -#ifndef UCHAR_MAX
2375      -#define UCHAR_MAX       255
2376      -#endif
2377      -
2378 2374  /*
2379      - * The entire pool (with maxcount entries) is pre-allocated at
2380      - * the first sigqueue/signotify call.
     2375 + * The pre-allocated pool (with _SIGQUEUE_PREALLOC entries) is
     2376 + * allocated at the first sigqueue/signotify call.
2381 2377   */
2382 2378  sigqhdr_t *
2383 2379  sigqhdralloc(size_t size, uint_t maxcount)
2384 2380  {
2385 2381          size_t i;
2386 2382          sigqueue_t *sq, *next;
2387 2383          sigqhdr_t *sqh;
2388 2384  
2389      -        i = (maxcount * size) + sizeof (sigqhdr_t);
2390      -        ASSERT(maxcount <= UCHAR_MAX && i <= USHRT_MAX);
     2385 +        /*
     2386 +         * Before the introduction of process.max-sigqueue-size
     2387 +         * _SC_SIGQUEUE_MAX had this static value.
     2388 +         */
     2389 +#define _SIGQUEUE_PREALLOC      32
     2390 +
     2391 +        i = (_SIGQUEUE_PREALLOC * size) + sizeof (sigqhdr_t);
     2392 +        ASSERT(maxcount <= INT_MAX);
2391 2393          sqh = kmem_alloc(i, KM_SLEEP);
2392      -        sqh->sqb_count = (uchar_t)maxcount;
2393      -        sqh->sqb_maxcount = (uchar_t)maxcount;
2394      -        sqh->sqb_size = (ushort_t)i;
     2394 +        sqh->sqb_count = maxcount;
     2395 +        sqh->sqb_maxcount = maxcount;
     2396 +        sqh->sqb_size = i;
2395 2397          sqh->sqb_pexited = 0;
2396 2398          sqh->sqb_sent = 0;
2397 2399          sqh->sqb_free = sq = (sigqueue_t *)(sqh + 1);
2398      -        for (i = maxcount - 1; i != 0; i--) {
     2400 +        for (i = _SIGQUEUE_PREALLOC - 1; i != 0; i--) {
2399 2401                  next = (sigqueue_t *)((uintptr_t)sq + size);
2400 2402                  sq->sq_next = next;
2401 2403                  sq = next;
2402 2404          }
2403 2405          sq->sq_next = NULL;
2404 2406          cv_init(&sqh->sqb_cv, NULL, CV_DEFAULT, NULL);
2405 2407          mutex_init(&sqh->sqb_lock, NULL, MUTEX_DEFAULT, NULL);
2406 2408          return (sqh);
2407 2409  }
2408 2410  
2409 2411  static void sigqrel(sigqueue_t *);
2410 2412  
2411 2413  /*
2412      - * allocate a sigqueue/signotify structure from the per process
2413      - * pre-allocated pool.
     2414 + * Allocate a sigqueue/signotify structure from the per process
     2415 + * pre-allocated pool or allocate a new sigqueue/signotify structure
     2416 + * if the pre-allocated pool is exhausted.
2414 2417   */
2415 2418  sigqueue_t *
2416 2419  sigqalloc(sigqhdr_t *sqh)
2417 2420  {
2418 2421          sigqueue_t *sq = NULL;
2419 2422  
2420 2423          ASSERT(MUTEX_HELD(&curproc->p_lock));
2421 2424  
2422 2425          if (sqh != NULL) {
2423 2426                  mutex_enter(&sqh->sqb_lock);
2424 2427                  if (sqh->sqb_count > 0) {
2425 2428                          sqh->sqb_count--;
2426      -                        sq = sqh->sqb_free;
2427      -                        sqh->sqb_free = sq->sq_next;
     2429 +                        if (sqh->sqb_free == NULL) {
     2430 +                                /*
     2431 +                                 * The pre-allocated pool is exhausted.
     2432 +                                 */
     2433 +                                sq = kmem_alloc(sizeof (sigqueue_t), KM_SLEEP);
     2434 +                                sq->sq_func = NULL;
     2435 +                        } else {
     2436 +                                sq = sqh->sqb_free;
     2437 +                                sq->sq_func = sigqrel;
     2438 +                                sqh->sqb_free = sq->sq_next;
     2439 +                        }
2428 2440                          mutex_exit(&sqh->sqb_lock);
2429 2441                          bzero(&sq->sq_info, sizeof (k_siginfo_t));
2430 2442                          sq->sq_backptr = sqh;
2431      -                        sq->sq_func = sigqrel;
2432 2443                          sq->sq_next = NULL;
2433 2444                          sq->sq_external = 0;
2434 2445                  } else {
2435 2446                          mutex_exit(&sqh->sqb_lock);
2436 2447                  }
2437 2448          }
2438 2449          return (sq);
2439 2450  }
2440 2451  
2441 2452  /*
↓ open down ↓ 420 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX