Print this page
11506 smatch resync

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/check_locking.c
          +++ new/usr/src/tools/smatch/src/check_locking.c
↓ open down ↓ 41 lines elided ↑ open up ↑
  42   42  
  43   43  enum action {
  44   44          LOCK,
  45   45          UNLOCK,
  46   46  };
  47   47  
  48   48  enum return_type {
  49   49          ret_any,
  50   50          ret_non_zero,
  51   51          ret_zero,
       52 +        ret_one,
  52   53          ret_negative,
  53   54          ret_positive,
  54   55  };
  55   56  
  56   57  #define RETURN_VAL -1
  57   58  #define NO_ARG -2
  58   59  
  59   60  struct lock_info {
  60   61          const char *function;
  61   62          enum action action;
↓ open down ↓ 82 lines elided ↑ open up ↑
 144  145          {"_spin_lock_irqsave_nested",  LOCK,   "spin_lock", 0, ret_any},
 145  146          {"__spin_lock_irqsave_nested", LOCK,   "spin_lock", 0, ret_any},
 146  147          {"_raw_spin_lock_irqsave_nested", LOCK, "spin_lock", 0, ret_any},
 147  148          {"spin_lock_bh",               LOCK,   "spin_lock", 0, ret_any},
 148  149          {"spin_unlock_bh",             UNLOCK, "spin_lock", 0, ret_any},
 149  150          {"_spin_lock_bh",              LOCK,   "spin_lock", 0, ret_any},
 150  151          {"_spin_unlock_bh",            UNLOCK, "spin_lock", 0, ret_any},
 151  152          {"__spin_lock_bh",             LOCK,   "spin_lock", 0, ret_any},
 152  153          {"__spin_unlock_bh",           UNLOCK, "spin_lock", 0, ret_any},
 153  154  
 154      -        {"spin_trylock",               LOCK,   "spin_lock", 0, ret_non_zero},
 155      -        {"_spin_trylock",              LOCK,   "spin_lock", 0, ret_non_zero},
 156      -        {"__spin_trylock",             LOCK,   "spin_lock", 0, ret_non_zero},
 157      -        {"raw_spin_trylock",           LOCK,   "spin_lock", 0, ret_non_zero},
 158      -        {"_raw_spin_trylock",          LOCK,   "spin_lock", 0, ret_non_zero},
 159      -        {"spin_trylock_irq",           LOCK,   "spin_lock", 0, ret_non_zero},
 160      -        {"spin_trylock_irqsave",       LOCK,   "spin_lock", 0, ret_non_zero},
 161      -        {"spin_trylock_bh",            LOCK,   "spin_lock", 0, ret_non_zero},
 162      -        {"_spin_trylock_bh",           LOCK,   "spin_lock", 0, ret_non_zero},
 163      -        {"__spin_trylock_bh",          LOCK,   "spin_lock", 0, ret_non_zero},
 164      -        {"__raw_spin_trylock",         LOCK,   "spin_lock", 0, ret_non_zero},
 165      -        {"_atomic_dec_and_lock",       LOCK,   "spin_lock", 1, ret_non_zero},
      155 +        {"spin_trylock",               LOCK,   "spin_lock", 0, ret_one},
      156 +        {"_spin_trylock",              LOCK,   "spin_lock", 0, ret_one},
      157 +        {"__spin_trylock",             LOCK,   "spin_lock", 0, ret_one},
      158 +        {"raw_spin_trylock",           LOCK,   "spin_lock", 0, ret_one},
      159 +        {"_raw_spin_trylock",          LOCK,   "spin_lock", 0, ret_one},
      160 +        {"spin_trylock_irq",           LOCK,   "spin_lock", 0, ret_one},
      161 +        {"spin_trylock_irqsave",       LOCK,   "spin_lock", 0, ret_one},
      162 +        {"spin_trylock_bh",            LOCK,   "spin_lock", 0, ret_one},
      163 +        {"_spin_trylock_bh",           LOCK,   "spin_lock", 0, ret_one},
      164 +        {"__spin_trylock_bh",          LOCK,   "spin_lock", 0, ret_one},
      165 +        {"__raw_spin_trylock",         LOCK,   "spin_lock", 0, ret_one},
      166 +        {"_atomic_dec_and_lock",       LOCK,   "spin_lock", 1, ret_one},
 166  167  
 167  168          {"read_lock",                 LOCK,   "read_lock", 0, ret_any},
 168  169          {"read_unlock",               UNLOCK, "read_lock", 0, ret_any},
 169  170          {"_read_lock",                LOCK,   "read_lock", 0, ret_any},
 170  171          {"_read_unlock",              UNLOCK, "read_lock", 0, ret_any},
 171  172          {"__read_lock",               LOCK,   "read_lock", 0, ret_any},
 172  173          {"__read_unlock",             UNLOCK, "read_lock", 0, ret_any},
 173  174          {"_raw_read_lock",            LOCK,   "read_lock", 0, ret_any},
 174  175          {"_raw_read_unlock",          UNLOCK, "read_lock", 0, ret_any},
 175  176          {"__raw_read_lock",           LOCK,   "read_lock", 0, ret_any},
↓ open down ↓ 14 lines elided ↑ open up ↑
 190  191          {"read_unlock_bh",            UNLOCK, "read_lock", 0, ret_any},
 191  192          {"_read_lock_bh",             LOCK,   "read_lock", 0, ret_any},
 192  193          {"_read_unlock_bh",           UNLOCK, "read_lock", 0, ret_any},
 193  194          {"__read_lock_bh",            LOCK,   "read_lock", 0, ret_any},
 194  195          {"__read_unlock_bh",          UNLOCK, "read_lock", 0, ret_any},
 195  196          {"_raw_read_lock_bh",         LOCK,   "read_lock", 0, ret_any},
 196  197          {"_raw_read_unlock_bh",       UNLOCK, "read_lock", 0, ret_any},
 197  198          {"__raw_read_lock_bh",        LOCK,   "read_lock", 0, ret_any},
 198  199          {"__raw_read_unlock_bh",      UNLOCK, "read_lock", 0, ret_any},
 199  200  
 200      -        {"generic__raw_read_trylock", LOCK,   "read_lock", 0, ret_non_zero},
 201      -        {"read_trylock",              LOCK,   "read_lock", 0, ret_non_zero},
 202      -        {"_read_trylock",             LOCK,   "read_lock", 0, ret_non_zero},
 203      -        {"raw_read_trylock",          LOCK,   "read_lock", 0, ret_non_zero},
 204      -        {"_raw_read_trylock",         LOCK,   "read_lock", 0, ret_non_zero},
 205      -        {"__raw_read_trylock",        LOCK,   "read_lock", 0, ret_non_zero},
 206      -        {"__read_trylock",            LOCK,   "read_lock", 0, ret_non_zero},
      201 +        {"generic__raw_read_trylock", LOCK,   "read_lock", 0, ret_one},
      202 +        {"read_trylock",              LOCK,   "read_lock", 0, ret_one},
      203 +        {"_read_trylock",             LOCK,   "read_lock", 0, ret_one},
      204 +        {"raw_read_trylock",          LOCK,   "read_lock", 0, ret_one},
      205 +        {"_raw_read_trylock",         LOCK,   "read_lock", 0, ret_one},
      206 +        {"__raw_read_trylock",        LOCK,   "read_lock", 0, ret_one},
      207 +        {"__read_trylock",            LOCK,   "read_lock", 0, ret_one},
 207  208  
 208  209          {"write_lock",                LOCK,   "write_lock", 0, ret_any},
 209  210          {"write_unlock",              UNLOCK, "write_lock", 0, ret_any},
 210  211          {"_write_lock",               LOCK,   "write_lock", 0, ret_any},
 211  212          {"_write_unlock",             UNLOCK, "write_lock", 0, ret_any},
 212  213          {"__write_lock",              LOCK,   "write_lock", 0, ret_any},
 213  214          {"__write_unlock",            UNLOCK, "write_lock", 0, ret_any},
 214  215          {"write_lock_irq",            LOCK,   "write_lock", 0, ret_any},
 215  216          {"write_unlock_irq",          UNLOCK, "write_lock", 0, ret_any},
 216  217          {"_write_lock_irq",           LOCK,   "write_lock", 0, ret_any},
↓ open down ↓ 10 lines elided ↑ open up ↑
 227  228          {"write_unlock_bh",           UNLOCK, "write_lock", 0, ret_any},
 228  229          {"_write_lock_bh",            LOCK,   "write_lock", 0, ret_any},
 229  230          {"_write_unlock_bh",          UNLOCK, "write_lock", 0, ret_any},
 230  231          {"__write_lock_bh",           LOCK,   "write_lock", 0, ret_any},
 231  232          {"__write_unlock_bh",         UNLOCK, "write_lock", 0, ret_any},
 232  233          {"_raw_write_lock",           LOCK,   "write_lock", 0, ret_any},
 233  234          {"__raw_write_lock",          LOCK,   "write_lock", 0, ret_any},
 234  235          {"_raw_write_unlock",         UNLOCK, "write_lock", 0, ret_any},
 235  236          {"__raw_write_unlock",        UNLOCK, "write_lock", 0, ret_any},
 236  237  
 237      -        {"write_trylock",             LOCK,   "write_lock", 0, ret_non_zero},
 238      -        {"_write_trylock",            LOCK,   "write_lock", 0, ret_non_zero},
 239      -        {"raw_write_trylock",         LOCK,   "write_lock", 0, ret_non_zero},
 240      -        {"_raw_write_trylock",        LOCK,   "write_lock", 0, ret_non_zero},
 241      -        {"__write_trylock",           LOCK,   "write_lock", 0, ret_non_zero},
 242      -        {"__raw_write_trylock",       LOCK,   "write_lock", 0, ret_non_zero},
      238 +        {"write_trylock",             LOCK,   "write_lock", 0, ret_one},
      239 +        {"_write_trylock",            LOCK,   "write_lock", 0, ret_one},
      240 +        {"raw_write_trylock",         LOCK,   "write_lock", 0, ret_one},
      241 +        {"_raw_write_trylock",        LOCK,   "write_lock", 0, ret_one},
      242 +        {"__write_trylock",           LOCK,   "write_lock", 0, ret_one},
      243 +        {"__raw_write_trylock",       LOCK,   "write_lock", 0, ret_one},
 243  244  
 244  245          {"down",               LOCK,   "sem", 0, ret_any},
 245  246          {"up",                 UNLOCK, "sem", 0, ret_any},
 246  247          {"down_trylock",       LOCK,   "sem", 0, ret_zero},
 247  248          {"down_timeout",       LOCK,   "sem", 0, ret_zero},
 248  249          {"down_interruptible", LOCK,   "sem", 0, ret_zero},
 249  250  
      251 +
      252 +        {"down_write",          LOCK,   "rw_sem", 0, ret_any},
      253 +        {"downgrade_write",     UNLOCK, "rw_sem", 0, ret_any},
      254 +        {"downgrade_write",     LOCK,   "read_sem", 0, ret_any},
      255 +        {"up_write",            UNLOCK, "rw_sem", 0, ret_any},
      256 +        {"down_write_trylock",  LOCK,   "rw_sem", 0, ret_one},
      257 +        {"down_write_killable", LOCK,   "rw_sem", 0, ret_zero},
      258 +        {"down_read",           LOCK,   "read_sem", 0, ret_any},
      259 +        {"down_read_trylock",   LOCK,   "read_sem", 0, ret_one},
      260 +        {"down_read_killable",  LOCK,   "read_sem", 0, ret_zero},
      261 +        {"up_read",             UNLOCK, "read_sem", 0, ret_any},
      262 +
 250  263          {"mutex_lock",                      LOCK,   "mutex", 0, ret_any},
      264 +        {"mutex_lock_io",                   LOCK,   "mutex", 0, ret_any},
 251  265          {"mutex_unlock",                    UNLOCK, "mutex", 0, ret_any},
 252  266          {"mutex_lock_nested",               LOCK,   "mutex", 0, ret_any},
      267 +        {"mutex_lock_io_nested",            LOCK,   "mutex", 0, ret_any},
 253  268  
 254  269          {"mutex_lock_interruptible",        LOCK,   "mutex", 0, ret_zero},
 255  270          {"mutex_lock_interruptible_nested", LOCK,   "mutex", 0, ret_zero},
 256  271          {"mutex_lock_killable",             LOCK,   "mutex", 0, ret_zero},
 257  272          {"mutex_lock_killable_nested",      LOCK,   "mutex", 0, ret_zero},
 258  273  
 259      -        {"mutex_trylock",                   LOCK,   "mutex", 0, ret_non_zero},
      274 +        {"mutex_trylock",                   LOCK,   "mutex", 0, ret_one},
 260  275  
 261  276          {"raw_local_irq_disable", LOCK,   "irq", NO_ARG, ret_any},
 262  277          {"raw_local_irq_enable",  UNLOCK, "irq", NO_ARG, ret_any},
 263  278          {"spin_lock_irq",         LOCK,   "irq", NO_ARG, ret_any},
 264  279          {"spin_unlock_irq",       UNLOCK, "irq", NO_ARG, ret_any},
 265  280          {"_spin_lock_irq",        LOCK,   "irq", NO_ARG, ret_any},
 266  281          {"_spin_unlock_irq",      UNLOCK, "irq", NO_ARG, ret_any},
 267  282          {"__spin_lock_irq",       LOCK,   "irq", NO_ARG, ret_any},
 268  283          {"__spin_unlock_irq",     UNLOCK, "irq", NO_ARG, ret_any},
 269  284          {"_raw_spin_lock_irq",    LOCK,   "irq", NO_ARG, ret_any},
 270  285          {"_raw_spin_unlock_irq",  UNLOCK, "irq", NO_ARG, ret_any},
 271  286          {"__raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
 272      -        {"spin_trylock_irq",      LOCK,   "irq", NO_ARG, ret_non_zero},
      287 +        {"spin_trylock_irq",      LOCK,   "irq", NO_ARG, ret_one},
 273  288          {"read_lock_irq",         LOCK,   "irq", NO_ARG, ret_any},
 274  289          {"read_unlock_irq",       UNLOCK, "irq", NO_ARG, ret_any},
 275  290          {"_read_lock_irq",        LOCK,   "irq", NO_ARG, ret_any},
 276  291          {"_read_unlock_irq",      UNLOCK, "irq", NO_ARG, ret_any},
 277  292          {"__read_lock_irq",       LOCK,   "irq", NO_ARG, ret_any},
 278  293          {"__read_unlock_irq",     UNLOCK, "irq", NO_ARG, ret_any},
 279  294          {"write_lock_irq",        LOCK,   "irq", NO_ARG, ret_any},
 280  295          {"write_unlock_irq",      UNLOCK, "irq", NO_ARG, ret_any},
 281  296          {"_write_lock_irq",       LOCK,   "irq", NO_ARG, ret_any},
 282  297          {"_write_unlock_irq",     UNLOCK, "irq", NO_ARG, ret_any},
↓ open down ↓ 14 lines elided ↑ open up ↑
 297  312          {"_spin_unlock_irqrestore",    UNLOCK, "irqsave", 1, ret_any},
 298  313          {"__spin_lock_irqsave_nested", LOCK,   "irqsave", 1, ret_any},
 299  314          {"__spin_lock_irqsave",        LOCK,   "irqsave", 1, ret_any},
 300  315          {"__spin_unlock_irqrestore",   UNLOCK, "irqsave", 1, ret_any},
 301  316          {"_raw_spin_lock_irqsave",     LOCK,   "irqsave", RETURN_VAL, ret_any},
 302  317          {"_raw_spin_lock_irqsave",     LOCK,   "irqsave", 1, ret_any},
 303  318          {"_raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any},
 304  319          {"__raw_spin_lock_irqsave",    LOCK,   "irqsave", RETURN_VAL, ret_any},
 305  320          {"__raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any},
 306  321          {"_raw_spin_lock_irqsave_nested", LOCK, "irqsave", RETURN_VAL, ret_any},
 307      -        {"spin_trylock_irqsave",       LOCK,   "irqsave", 1, ret_non_zero},
      322 +        {"spin_trylock_irqsave",       LOCK,   "irqsave", 1, ret_one},
 308  323          {"read_lock_irqsave",          LOCK,   "irqsave", RETURN_VAL, ret_any},
 309  324          {"read_lock_irqsave",          LOCK,   "irqsave", 1, ret_any},
 310  325          {"read_unlock_irqrestore",     UNLOCK, "irqsave", 1, ret_any},
 311  326          {"_read_lock_irqsave",         LOCK,   "irqsave", RETURN_VAL, ret_any},
 312  327          {"_read_lock_irqsave",         LOCK,   "irqsave", 1, ret_any},
 313  328          {"_read_unlock_irqrestore",    UNLOCK, "irqsave", 1, ret_any},
 314  329          {"__read_lock_irqsave",        LOCK,   "irqsave", RETURN_VAL, ret_any},
 315  330          {"__read_unlock_irqrestore",   UNLOCK, "irqsave", 1, ret_any},
 316  331          {"write_lock_irqsave",         LOCK,   "irqsave", RETURN_VAL, ret_any},
 317  332          {"write_lock_irqsave",         LOCK,   "irqsave", 1, ret_any},
↓ open down ↓ 23 lines elided ↑ open up ↑
 341  356          {"__read_lock_bh",      LOCK,   "bottom_half", NO_ARG, ret_any},
 342  357          {"__read_unlock_bh",    UNLOCK, "bottom_half", NO_ARG, ret_any},
 343  358          {"_raw_read_lock_bh",   LOCK,   "bottom_half", NO_ARG, ret_any},
 344  359          {"_raw_read_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any},
 345  360          {"write_lock_bh",       LOCK,   "bottom_half", NO_ARG, ret_any},
 346  361          {"write_unlock_bh",     UNLOCK, "bottom_half", NO_ARG, ret_any},
 347  362          {"_write_lock_bh",      LOCK,   "bottom_half", NO_ARG, ret_any},
 348  363          {"_write_unlock_bh",    UNLOCK, "bottom_half", NO_ARG, ret_any},
 349  364          {"__write_lock_bh",     LOCK,   "bottom_half", NO_ARG, ret_any},
 350  365          {"__write_unlock_bh",   UNLOCK, "bottom_half", NO_ARG, ret_any},
 351      -        {"spin_trylock_bh",     LOCK,   "bottom_half", NO_ARG, ret_non_zero},
 352      -        {"_spin_trylock_bh",    LOCK,   "bottom_half", NO_ARG, ret_non_zero},
 353      -        {"__spin_trylock_bh",   LOCK,   "bottom_half", NO_ARG, ret_non_zero},
      366 +        {"spin_trylock_bh",     LOCK,   "bottom_half", NO_ARG, ret_one},
      367 +        {"_spin_trylock_bh",    LOCK,   "bottom_half", NO_ARG, ret_one},
      368 +        {"__spin_trylock_bh",   LOCK,   "bottom_half", NO_ARG, ret_one},
 354  369  
 355  370          {"ffs_mutex_lock",        LOCK,   "mutex", 0, ret_zero},
 356  371  };
 357  372  
 358  373  static struct lock_info *lock_table;
 359  374  
 360  375  static struct tracker_list *starts_locked;
 361  376  static struct tracker_list *starts_unlocked;
 362  377  
 363  378  struct locks_on_return {
↓ open down ↓ 76 lines elided ↑ open up ↑
 440  455  {
 441  456          return &start_state;
 442  457  }
 443  458  
 444  459  static void pre_merge_hook(struct sm_state *sm)
 445  460  {
 446  461          if (is_impossible_path())
 447  462                  set_state(my_id, sm->name, sm->sym, &impossible);
 448  463  }
 449  464  
      465 +static bool nestable(const char *name)
      466 +{
      467 +        if (strstr(name, "read_sem:"))
      468 +                return true;
      469 +        if (strcmp(name, "bottom_half:") == 0)
      470 +                return true;
      471 +        return false;
      472 +}
      473 +
 450  474  static void do_lock(const char *name)
 451  475  {
 452  476          struct sm_state *sm;
 453  477  
 454  478          if (__inline_fn)
 455  479                  return;
 456  480  
 457  481          sm = get_sm_state(my_id, name, NULL);
 458  482          if (!sm)
 459  483                  add_tracker(&starts_unlocked, my_id, name, NULL);
 460      -        if (sm && slist_has_state(sm->possible, &locked) &&
 461      -                        strcmp(name, "bottom_half:") != 0)
      484 +        if (sm && slist_has_state(sm->possible, &locked) && !nestable(name))
 462  485                  sm_error("double lock '%s'", name);
 463  486          if (sm)
 464  487                  func_has_transition = TRUE;
 465  488          set_state(my_id, name, NULL, &locked);
 466  489  }
 467  490  
 468  491  static void do_lock_failed(const char *name)
 469  492  {
 470  493          struct sm_state *sm;
 471  494  
↓ open down ↓ 265 lines elided ↑ open up ↑
 737  760                                  sm_printf("               ");
 738  761                          sm_printf("line %d\n", tmp->line);
 739  762                          add_line(&printed, tmp->line);
 740  763                  }
 741  764          } END_FOR_EACH_PTR(tmp);
 742  765  }
 743  766  
 744  767  static int matches_return_type(struct range_list *rl, enum return_type type)
 745  768  {
 746  769          sval_t zero_sval = ll_to_sval(0);
      770 +        sval_t one_sval = ll_to_sval(1);
 747  771  
 748  772          /* All these double negatives are super ugly!  */
 749  773  
 750  774          switch (type) {
 751  775          case ret_zero:
 752  776                  return !possibly_true_rl(rl, SPECIAL_NOTEQUAL, alloc_rl(zero_sval, zero_sval));
      777 +        case ret_one:
      778 +                return !possibly_true_rl(rl, SPECIAL_NOTEQUAL, alloc_rl(one_sval, one_sval));
 753  779          case ret_non_zero:
 754  780                  return !possibly_true_rl(rl, SPECIAL_EQUAL, alloc_rl(zero_sval, zero_sval));
 755  781          case ret_negative:
 756  782                  return !possibly_true_rl(rl, SPECIAL_GTE, alloc_rl(zero_sval, zero_sval));
 757  783          case ret_positive:
 758  784                  return !possibly_true_rl(rl, '<', alloc_rl(zero_sval, zero_sval));
 759  785          case ret_any:
 760  786          default:
 761  787                  return 1;
 762  788          }
↓ open down ↓ 136 lines elided ↑ open up ↑
 899  925                  return;
 900  926          clear_lists();
 901  927  }
 902  928  
 903  929  static void register_lock(int index)
 904  930  {
 905  931          struct lock_info *lock = &lock_table[index];
 906  932          void *idx = INT_PTR(index);
 907  933  
 908  934          if (lock->return_type == ret_non_zero) {
 909      -                return_implies_state(lock->function, valid_ptr_min, valid_ptr_max, &match_lock_held, idx);
      935 +                return_implies_state(lock->function, 1, INT_MAX, &match_lock_held, idx);
 910  936                  return_implies_state(lock->function, 0, 0, &match_lock_failed, idx);
 911  937          } else if (lock->return_type == ret_any && lock->arg == RETURN_VAL) {
 912  938                  add_function_assign_hook(lock->function, &match_returns_locked, idx);
 913  939          } else if (lock->return_type == ret_any) {
 914  940                  add_function_hook(lock->function, &match_lock_unlock, idx);
 915  941          } else if (lock->return_type == ret_zero) {
 916  942                  return_implies_state(lock->function, 0, 0, &match_lock_held, idx);
 917  943                  return_implies_state(lock->function, -4095, -1, &match_lock_failed, idx);
      944 +        } else if (lock->return_type == ret_one) {
      945 +                return_implies_state(lock->function, 1, 1, &match_lock_held, idx);
      946 +                return_implies_state(lock->function, 0, 0, &match_lock_failed, idx);
 918  947          }
 919  948  }
 920  949  
 921  950  static void load_table(struct lock_info *_lock_table, int size)
 922  951  {
 923  952          int i;
 924  953  
 925  954          lock_table = _lock_table;
 926  955  
 927  956          for (i = 0; i < size; i++) {
↓ open down ↓ 42 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX