Print this page
11927 Log, or optionally panic, on zero-length kmem allocations
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Jason King <jason.brian.king@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/portfs/port.c
          +++ new/usr/src/uts/common/fs/portfs/port.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
       27 +/*
       28 + * Copyright (c) 2015 Joyent, Inc.  All rights reserved.
       29 + */
       30 +
  27   31  #include <sys/types.h>
  28   32  #include <sys/systm.h>
  29   33  #include <sys/cred.h>
  30   34  #include <sys/modctl.h>
  31   35  #include <sys/vfs.h>
  32   36  #include <sys/vfs_opreg.h>
  33   37  #include <sys/sysmacros.h>
  34   38  #include <sys/cmn_err.h>
  35   39  #include <sys/stat.h>
  36   40  #include <sys/errno.h>
↓ open down ↓ 1335 lines elided ↑ open up ↑
1372 1376          /* move port event queue to a temporary queue */
1373 1377          list_move_tail(&portq->portq_get_list, &portq->portq_list);
1374 1378          glist = &portq->portq_get_list; /* use temporary event queue */
1375 1379          tnent = portq->portq_nent;      /* get current number of events */
1376 1380          portq->portq_nent = 0;          /* no events in the port event queue */
1377 1381          portq->portq_flags |= PORTQ_WAIT_EVENTS; /* detect incoming events */
1378 1382          mutex_exit(&portq->portq_mutex);    /* event queue can be reused now */
1379 1383  
1380 1384          if (model == DATAMODEL_NATIVE) {
1381 1385                  eventsz = sizeof (port_event_t);
1382      -                kevp = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
1383      -                if (kevp == NULL) {
1384      -                        if (nmax > pp->port_max_list)
1385      -                                nmax = pp->port_max_list;
1386      -                        kevp = kmem_alloc(eventsz * nmax, KM_SLEEP);
     1386 +
     1387 +                if (nmax == 0) {
     1388 +                        kevp = NULL;
     1389 +                } else {
     1390 +                        kevp = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
     1391 +                        if (kevp == NULL) {
     1392 +                                if (nmax > pp->port_max_list)
     1393 +                                        nmax = pp->port_max_list;
     1394 +                                kevp = kmem_alloc(eventsz * nmax, KM_SLEEP);
     1395 +                        }
1387 1396                  }
     1397 +
1388 1398                  results = kevp;
1389 1399                  lev = NULL;     /* start with first event in the queue */
1390 1400                  for (nevents = 0; nevents < nmax; ) {
1391 1401                          pev = port_get_kevent(glist, lev);
1392 1402                          if (pev == NULL)        /* no more events available */
1393 1403                                  break;
1394 1404                          if (pev->portkev_flags & PORT_KEV_FREE) {
1395 1405                                  /* Just discard event */
1396 1406                                  list_remove(glist, pev);
1397 1407                                  pev->portkev_flags &= ~(PORT_CLEANUP_DONE);
↓ open down ↓ 16 lines elided ↑ open up ↑
1414 1424                                  lev = pev;  /* last checked event */
1415 1425                          } else {
1416 1426                                  nevents++;      /* # of events ready */
1417 1427                          }
1418 1428                  }
1419 1429  #ifdef  _SYSCALL32_IMPL
1420 1430          } else {
1421 1431                  port_event32_t  *kevp32;
1422 1432  
1423 1433                  eventsz = sizeof (port_event32_t);
1424      -                kevp32 = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
1425      -                if (kevp32 == NULL) {
1426      -                        if (nmax > pp->port_max_list)
1427      -                                nmax = pp->port_max_list;
1428      -                        kevp32 = kmem_alloc(eventsz * nmax, KM_SLEEP);
     1434 +
     1435 +                if (nmax == 0) {
     1436 +                        kevp32 = NULL;
     1437 +                } else {
     1438 +                        kevp32 = kmem_alloc(eventsz * nmax, KM_NOSLEEP);
     1439 +                        if (kevp32 == NULL) {
     1440 +                                if (nmax > pp->port_max_list)
     1441 +                                        nmax = pp->port_max_list;
     1442 +                                kevp32 = kmem_alloc(eventsz * nmax, KM_SLEEP);
     1443 +                        }
1429 1444                  }
     1445 +
1430 1446                  results = kevp32;
1431 1447                  lev = NULL;     /* start with first event in the queue */
1432 1448                  for (nevents = 0; nevents < nmax; ) {
1433 1449                          pev = port_get_kevent(glist, lev);
1434 1450                          if (pev == NULL)        /* no more events available */
1435 1451                                  break;
1436 1452                          if (pev->portkev_flags & PORT_KEV_FREE) {
1437 1453                                  /* Just discard event */
1438 1454                                  list_remove(glist, pev);
1439 1455                                  pev->portkev_flags &= ~(PORT_CLEANUP_DONE);
↓ open down ↓ 436 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX