Print this page
8634 epoll fails to wake on certain edge-triggered conditions
8635 epoll should not emit POLLNVAL
8636 recursive epoll should emit EPOLLRDNORM
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/rsm/rsm.c
          +++ new/usr/src/uts/common/io/rsm/rsm.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   * Copyright 2012 Milan Jurik. All rights reserved.
  25   25   * Copyright (c) 2016 by Delphix. All rights reserved.
       26 + * Copyright 2017 Joyent, Inc.
  26   27   */
  27   28  
  28   29  
  29   30  /*
  30   31   * Overview of the RSM Kernel Agent:
  31   32   * ---------------------------------
  32   33   *
  33   34   * rsm.c constitutes the implementation of the RSM kernel agent. The RSM
  34   35   * kernel agent is a pseudo device driver which makes use of the RSMPI
  35   36   * interface on behalf of the RSMAPI user library.
↓ open down ↓ 2376 lines elided ↑ open up ↑
2412 2413                  }
2413 2414          }
2414 2415  
2415 2416          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsm_bind done\n"));
2416 2417  
2417 2418          return (e);
2418 2419  }
2419 2420  
2420 2421  static void
2421 2422  rsm_remap_local_importers(rsm_node_id_t src_nodeid,
2422      -    rsm_memseg_id_t ex_segid,
2423      -    ddi_umem_cookie_t cookie)
2424      -
     2423 +    rsm_memseg_id_t ex_segid, ddi_umem_cookie_t cookie)
2425 2424  {
2426 2425          rsmresource_t   *p = NULL;
2427 2426          rsmhash_table_t *rhash = &rsm_import_segs;
2428 2427          uint_t          index;
2429 2428  
2430 2429          DBG_PRINTF((RSM_KERNEL_AGENT | RSM_FUNC_ALL, RSM_DEBUG_VERBOSE,
2431 2430              "rsm_remap_local_importers enter\n"));
2432 2431  
2433 2432          index = rsmhash(ex_segid);
2434 2433  
↓ open down ↓ 1202 lines elided ↑ open up ↑
3637 3636  /*
3638 3637   * When an exported segment is unpublished the exporter sends an ipc
3639 3638   * message (RSMIPC_MSG_DISCONNECT) to all importers.  The recv ipc dispatcher
3640 3639   * calls this function.  The import list is scanned; segments which match the
3641 3640   * exported segment id are unloaded and disconnected.
3642 3641   *
3643 3642   * Will also be called from rsm_rebind with disconnect_flag FALSE.
3644 3643   *
3645 3644   */
3646 3645  static void
3647      -rsm_force_unload(rsm_node_id_t src_nodeid,
3648      -    rsm_memseg_id_t ex_segid,
     3646 +rsm_force_unload(rsm_node_id_t src_nodeid, rsm_memseg_id_t ex_segid,
3649 3647      boolean_t disconnect_flag)
3650      -
3651 3648  {
3652 3649          rsmresource_t   *p = NULL;
3653 3650          rsmhash_table_t *rhash = &rsm_import_segs;
3654 3651          uint_t          index;
3655 3652          DBG_DEFINE(category,
3656 3653              RSM_KERNEL_AGENT | RSM_FUNC_ALL | RSM_INTR_CALLBACK);
3657 3654  
3658 3655          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsm_force_unload enter\n"));
3659 3656  
3660 3657          index = rsmhash(ex_segid);
↓ open down ↓ 3094 lines elided ↑ open up ↑
6755 6752                  (void) rsmipc_send(seg->s_node, &request, RSM_NO_REPLY);
6756 6753          } else {
6757 6754                  rsmseglock_release(seg);
6758 6755          }
6759 6756  
6760 6757          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsm_disconnect done\n"));
6761 6758  
6762 6759          return (DDI_SUCCESS);
6763 6760  }
6764 6761  
6765      -/*ARGSUSED*/
6766 6762  static int
6767 6763  rsm_chpoll(dev_t dev, short events, int anyyet, short *reventsp,
6768 6764      struct pollhead **phpp)
6769 6765  {
6770 6766          minor_t         rnum;
6771 6767          rsmresource_t   *res;
6772 6768          rsmseg_t        *seg;
6773 6769          DBG_DEFINE(category, RSM_KERNEL_AGENT | RSM_FUNC_ALL | RSM_DDI);
6774 6770  
6775 6771          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsm_chpoll enter\n"));
↓ open down ↓ 1 lines elided ↑ open up ↑
6777 6773          /* find minor, no lock */
6778 6774          rnum = getminor(dev);
6779 6775          res = rsmresource_lookup(rnum, RSM_NOLOCK);
6780 6776  
6781 6777          /* poll is supported only for export/import segments */
6782 6778          if ((res == NULL) || (res == RSMRC_RESERVED) ||
6783 6779              (res->rsmrc_type == RSM_RESOURCE_BAR)) {
6784 6780                  return (ENXIO);
6785 6781          }
6786 6782  
6787      -        *reventsp = 0;
6788      -
6789 6783          /*
6790 6784           * An exported segment must be in state RSM_STATE_EXPORT; an
6791 6785           * imported segment must be in state RSM_STATE_ACTIVE.
6792 6786           */
6793 6787          seg = (rsmseg_t *)res;
6794 6788  
6795 6789          if (seg->s_pollevent) {
6796 6790                  *reventsp = POLLRDNORM;
6797      -        } else if (!anyyet) {
     6791 +        } else {
     6792 +                *reventsp = 0;
     6793 +        }
     6794 +
     6795 +        if ((*reventsp == 0 && !anyyet) || (events & POLLET)) {
6798 6796                  /* cannot take segment lock here */
6799 6797                  *phpp = &seg->s_poll;
6800 6798                  seg->s_pollflag |= RSM_SEGMENT_POLL;
6801 6799          }
6802 6800          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsm_chpoll done\n"));
6803 6801          return (0);
6804 6802  }
6805 6803  
6806 6804  
6807 6805  
↓ open down ↓ 1473 lines elided ↑ open up ↑
8281 8279          }
8282 8280  
8283 8281  
8284 8282          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsmmap_access done\n"));
8285 8283  
8286 8284          return (e);
8287 8285  }
8288 8286  
8289 8287  static int
8290 8288  rsmmap_dup(devmap_cookie_t dhp, void *oldpvt, devmap_cookie_t new_dhp,
8291      -        void **newpvt)
     8289 +    void **newpvt)
8292 8290  {
8293 8291          rsmseg_t        *seg = (rsmseg_t *)oldpvt;
8294 8292          rsmcookie_t     *p, *old;
8295 8293          DBG_DEFINE(category, RSM_KERNEL_AGENT | RSM_FUNC_ALL | RSM_DDI);
8296 8294  
8297 8295          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsmmap_dup enter\n"));
8298 8296  
8299 8297          /*
8300 8298           * Same as map, create an entry to hold cookie and add it to
8301 8299           * connect segment list. The oldpvt is a pointer to segment.
↓ open down ↓ 30 lines elided ↑ open up ↑
8332 8330  
8333 8331          rsmseglock_release(seg);
8334 8332  
8335 8333          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsmmap_dup done\n"));
8336 8334  
8337 8335          return (DDI_SUCCESS);
8338 8336  }
8339 8337  
8340 8338  static void
8341 8339  rsmmap_unmap(devmap_cookie_t dhp, void *pvtp, offset_t off, size_t len,
8342      -        devmap_cookie_t new_dhp1, void **pvtp1,
8343      -        devmap_cookie_t new_dhp2, void **pvtp2)
     8340 +    devmap_cookie_t new_dhp1, void **pvtp1,
     8341 +    devmap_cookie_t new_dhp2, void **pvtp2)
8344 8342  {
8345 8343          /*
8346 8344           * Remove pvtp structure from segment list.
8347 8345           */
8348 8346          rsmseg_t        *seg = (rsmseg_t *)pvtp;
8349 8347          int freeflag;
8350 8348  
8351 8349          DBG_DEFINE(category, RSM_KERNEL_AGENT | RSM_FUNC_ALL | RSM_DDI);
8352 8350  
8353 8351          DBG_PRINTF((category, RSM_DEBUG_VERBOSE, "rsmmap_unmap enter\n"));
↓ open down ↓ 1328 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX