Print this page
Revert "NEX-20260 NFS hung in transitional state when RSF marks it maintenance"
This reverts commit 9bf6e5f740709f470ba350df64cd9f2c93f3f0a7.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs4_db.c
          +++ new/usr/src/uts/common/fs/nfs/nfs4_db.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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
  25   25  
  26   26  /*
  27      - * Copyright 2019 Nexenta Systems, Inc.
       27 + * Copyright 2018 Nexenta Systems, Inc.
  28   28   */
  29   29  
  30   30  #include <sys/systm.h>
  31   31  #include <sys/cmn_err.h>
  32   32  #include <sys/kmem.h>
  33   33  #include <sys/disp.h>
  34   34  #include <sys/id_space.h>
       35 +#include <sys/atomic.h>
  35   36  #include <rpc/rpc.h>
  36   37  #include <nfs/nfs4.h>
  37   38  #include <nfs/nfs4_db_impl.h>
  38   39  #include <sys/sdt.h>
  39   40  
  40   41  static int rfs4_reap_interval = RFS4_REAP_INTERVAL;
  41   42  
  42   43  static void rfs4_dbe_reap(rfs4_table_t *, time_t, uint32_t);
  43   44  static void rfs4_dbe_destroy(rfs4_dbe_t *);
  44   45  static rfs4_dbe_t *rfs4_dbe_create(rfs4_table_t *, id_t, rfs4_entry_t);
↓ open down ↓ 12 lines elided ↑ open up ↑
  57   58  
  58   59  id_t
  59   60  rfs4_dbe_getid(rfs4_dbe_t *entry)
  60   61  {
  61   62          return (entry->dbe_id);
  62   63  }
  63   64  
  64   65  void
  65   66  rfs4_dbe_hold(rfs4_dbe_t *entry)
  66   67  {
  67      -        if (!MUTEX_HELD(entry->dbe_lock)) {
  68      -                mutex_enter(entry->dbe_lock);
  69      -                entry->dbe_refcnt++;
  70      -                mutex_exit(entry->dbe_lock);
  71      -        } else {
  72      -                entry->dbe_refcnt++;
  73      -        }
       68 +        atomic_inc_32(&entry->dbe_refcnt);
  74   69  }
  75   70  
  76   71  /*
  77   72   * rfs4_dbe_rele_nolock only decrements the reference count of the entry.
  78   73   */
  79   74  void
  80   75  rfs4_dbe_rele_nolock(rfs4_dbe_t *entry)
  81   76  {
  82      -        if (!MUTEX_HELD(entry->dbe_lock)) {
  83      -                ASSERT(entry->dbe_refcnt > 0);
  84      -                mutex_enter(entry->dbe_lock);
  85      -                entry->dbe_refcnt--;
  86      -                mutex_exit(entry->dbe_lock);
  87      -        } else {
  88      -                entry->dbe_refcnt--;
  89      -        }
       77 +        atomic_dec_32(&entry->dbe_refcnt);
  90   78  }
  91   79  
  92   80  
  93   81  uint32_t
  94   82  rfs4_dbe_refcnt(rfs4_dbe_t *entry)
  95   83  {
  96   84          return (entry->dbe_refcnt);
  97   85  }
  98   86  
  99   87  /*
 100   88   * Mark an entry such that the dbsearch will skip it.
 101   89   * Caller does not want this entry to be found any longer
 102   90   */
 103   91  void
 104   92  rfs4_dbe_invalidate(rfs4_dbe_t *entry)
 105   93  {
 106      -        if (!MUTEX_HELD(entry->dbe_lock)) {
 107      -                mutex_enter(entry->dbe_lock);
 108      -                entry->dbe_invalid = TRUE;
 109      -                entry->dbe_skipsearch = TRUE;
 110      -                mutex_exit(entry->dbe_lock);
 111      -        } else {
 112      -                entry->dbe_invalid = TRUE;
 113      -                entry->dbe_skipsearch = TRUE;
 114      -        }
       94 +        entry->dbe_invalid = TRUE;
       95 +        entry->dbe_skipsearch = TRUE;
 115   96  }
 116   97  
 117   98  /*
 118   99   * Is this entry invalid?
 119  100   */
 120  101  bool_t
 121  102  rfs4_dbe_is_invalid(rfs4_dbe_t *entry)
 122  103  {
 123  104          return (entry->dbe_invalid);
 124  105  }
↓ open down ↓ 21 lines elided ↑ open up ↑
 146  127          rfs4_dbe_lock(entry);
 147  128          entry->dbe_skipsearch = FALSE;
 148  129          rfs4_dbe_unlock(entry);
 149  130  }
 150  131  
 151  132  void
 152  133  rfs4_dbe_rele(rfs4_dbe_t *entry)
 153  134  {
 154  135          mutex_enter(entry->dbe_lock);
 155  136          ASSERT(entry->dbe_refcnt > 1);
 156      -        entry->dbe_refcnt--;
      137 +        atomic_dec_32(&entry->dbe_refcnt);
 157  138          entry->dbe_time_rele = gethrestime_sec();
 158  139          mutex_exit(entry->dbe_lock);
 159  140  }
 160  141  
 161  142  void
 162  143  rfs4_dbe_lock(rfs4_dbe_t *entry)
 163  144  {
 164  145          mutex_enter(entry->dbe_lock);
 165  146  }
 166  147  
↓ open down ↓ 667 lines elided ↑ open up ↑
 834  815          bool_t found;
 835  816          int i;
 836  817          int count = 0;
 837  818  
 838  819          NFS4_DEBUG(table->dbt_debug & REAP_DEBUG,
 839  820              (CE_NOTE, "Reaping %d entries older than %ld seconds in table %s",
 840  821              desired, cache_time, table->dbt_name));
 841  822  
 842  823          /* Walk the buckets looking for entries to release/destroy */
 843  824          for (i = 0; i < table->dbt_len; i++) {
 844      -                int retries = 0;
 845  825                  bp = &buckets[i];
 846  826                  do {
 847  827                          found = FALSE;
 848  828                          rw_enter(bp->dbk_lock, RW_READER);
 849  829                          for (l = bp->dbk_head; l; l = l->next) {
 850  830                                  entry = l->entry;
 851      -                                mutex_enter(entry->dbe_lock);
 852      -                                ASSERT(entry->dbe_refcnt != 0);
 853  831                                  /*
 854  832                                   * Examine an entry.  Ref count of 1 means
 855  833                                   * that the only reference is for the hash
 856  834                                   * table reference.
 857  835                                   */
 858      -                                if (entry->dbe_refcnt != 1) {
 859      -                                        mutex_exit(entry->dbe_lock);
      836 +                                if (entry->dbe_refcnt != 1)
 860  837                                          continue;
 861      -                                }
      838 +                                mutex_enter(entry->dbe_lock);
 862  839                                  if ((entry->dbe_refcnt == 1) &&
 863  840                                      (table->dbt_reaper_shutdown ||
 864  841                                      table->dbt_expiry == NULL ||
 865  842                                      (*table->dbt_expiry)(entry->dbe_data))) {
 866      -                                        rfs4_dbe_rele_nolock(entry);
      843 +                                        entry->dbe_refcnt--;
 867  844                                          count++;
 868  845                                          found = TRUE;
 869  846                                  }
 870  847                                  mutex_exit(entry->dbe_lock);
 871  848                          }
 872  849                          if (found) {
 873  850                                  if (!rw_tryupgrade(bp->dbk_lock)) {
 874  851                                          rw_exit(bp->dbk_lock);
 875  852                                          rw_enter(bp->dbk_lock, RW_WRITER);
 876  853                                  }
 877  854  
 878  855                                  l = bp->dbk_head;
 879  856                                  while (l) {
 880  857                                          t = l;
 881  858                                          entry = t->entry;
 882  859                                          l = l->next;
 883      -                                        mutex_enter(entry->dbe_lock);
 884  860                                          if (entry->dbe_refcnt == 0) {
 885  861                                                  DEQUEUE(bp->dbk_head, t);
 886      -                                                mutex_exit(entry->dbe_lock);
 887  862                                                  t->next = NULL;
 888  863                                                  t->prev = NULL;
 889  864                                                  INVALIDATE_ADDR(t->entry);
 890  865                                                  rfs4_dbe_destroy(entry);
 891      -                                        } else
 892      -                                                mutex_exit(entry->dbe_lock);
      866 +                                        }
 893  867                                  }
 894  868                          }
 895  869                          rw_exit(bp->dbk_lock);
 896  870                          /*
 897  871                           * delay slightly if there is more work to do
 898  872                           * with the expectation that other reaper
 899  873                           * threads are freeing data structures as well
 900  874                           * and in turn will reduce ref counts on
 901  875                           * entries in this table allowing them to be
 902  876                           * released.  This is only done in the
 903  877                           * instance that the tables are being shut down.
 904  878                           */
 905      -                        if (table->dbt_reaper_shutdown && bp->dbk_head != NULL) {
      879 +                        if (table->dbt_reaper_shutdown && bp->dbk_head != NULL)
 906  880                                  delay(hz/100);
 907      -                                retries++;
 908      -                        }
 909  881                  /*
 910  882                   * If this is a table shutdown, keep going until
 911  883                   * everything is gone
 912  884                   */
 913      -                } while (table->dbt_reaper_shutdown && bp->dbk_head != NULL && retries < 5);
      885 +                } while (table->dbt_reaper_shutdown && bp->dbk_head != NULL);
 914  886  
 915  887                  if (!table->dbt_reaper_shutdown && desired && count >= desired)
 916  888                          break;
 917  889          }
 918  890  
 919  891          NFS4_DEBUG(table->dbt_debug & REAP_DEBUG,
 920  892              (CE_NOTE, "Reaped %d entries older than %ld seconds in table %s",
 921  893              count, cache_time, table->dbt_name));
 922  894  }
 923  895  
↓ open down ↓ 56 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX