An error occurred fetching the project authors.
  1. 14 Aug, 2023 1 commit
    • Dietmar Eggemann's avatar
      torture: Add lock_torture writer_fifo module parameter · 5d248bb3
      Dietmar Eggemann authored
      This commit adds a module parameter that causes the locktorture writer
      to run at real-time priority.
      
      To use it:
      insmod /lib/modules/torture.ko random_shuffle=1
      insmod /lib/modules/locktorture.ko torture_type=mutex_lock rt_boost=1 rt_boost_factor=50 nested_locks=3 writer_fifo=1
      													^^^^^^^^^^^^^
      
      A predecessor to this patch has been helpful to uncover issues with the
      proxy-execution series.
      
      [ paulmck: Remove locktorture-specific code from kernel/torture.c. ]
      
      Cc: "Paul E. McKenney" <paulmck@kernel.org>
      Cc: Josh Triplett <josh@joshtriplett.org>
      Cc: Joel Fernandes <joel@joelfernandes.org>
      Cc: Juri Lelli <juri.lelli@redhat.com>
      Cc: Valentin Schneider <vschneid@redhat.com>
      Cc: kernel-team@android.com
      Signed-off-by: default avatarDietmar Eggemann <dietmar.eggemann@arm.com>
      [jstultz: Include header change to build, reword commit message]
      Signed-off-by: default avatarJohn Stultz <jstultz@google.com>
      Acked-by: default avatarDavidlohr Bueso <dave@stgolabs.net>
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      5d248bb3
  2. 11 May, 2023 1 commit
  3. 07 Mar, 2023 5 commits
  4. 05 Jan, 2023 2 commits
  5. 08 Dec, 2021 1 commit
  6. 13 Sep, 2021 1 commit
  7. 27 Jul, 2021 2 commits
    • Paul E. McKenney's avatar
      locktorture: Count lock readers · af5f6e27
      Paul E. McKenney authored
      Currently, the lock_is_read_held variable is bool, so that a reader sets
      it to true just after lock acquisition and then to false just before
      lock release.  This works in a rough statistical sense, but can result
      in false negatives just after one of a pair of concurrent readers has
      released the lock.  This approach does have low overhead, but at the
      expense of the setting to true potentially never leaving the reader's
      store buffer, thus resulting in an unconditional false negative.
      
      This commit therefore converts this variable to atomic_t and makes
      the reader use atomic_inc() just after acquisition and atomic_dec()
      just before release.  This does increase overhead, but this increase is
      negligible compared to the 10-microsecond lock hold time.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      af5f6e27
    • Paul E. McKenney's avatar
      locktorture: Mark statistics data races · 5b237d65
      Paul E. McKenney authored
      The lock_stress_stats structure's ->n_lock_fail and ->n_lock_acquired
      fields are incremented and sampled locklessly using plain C-language
      statements, which KCSAN objects to.  This commit therefore marks the
      statistics gathering with data_race() to flag the intent.  While in
      the area, this commit also reduces the number of accesses to the
      ->n_lock_acquired field, thus eliminating some possible check/use
      confusion.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      5b237d65
  8. 19 Mar, 2021 3 commits
  9. 04 Jan, 2021 1 commit
  10. 07 Nov, 2020 4 commits
    • Hou Tao's avatar
      locktorture: Invoke percpu_free_rwsem() to do percpu-rwsem cleanup · 0d720287
      Hou Tao authored
      When executing the LOCK06 locktorture scenario featuring percpu-rwsem,
      the RCU callback rcu_sync_func() may still be pending after locktorture
      module is removed.  This can in turn lead to the following Oops:
      
        BUG: unable to handle page fault for address: ffffffffc00eb920
        #PF: supervisor read access in kernel mode
        #PF: error_code(0x0000) - not-present page
        PGD 6500a067 P4D 6500a067 PUD 6500c067 PMD 13a36c067 PTE 800000013691c163
        Oops: 0000 [#1] PREEMPT SMP
        CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.9.0-rc5+ #4
        Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
        RIP: 0010:rcu_cblist_dequeue+0x12/0x30
        Call Trace:
         <IRQ>
         rcu_core+0x1b1/0x860
         __do_softirq+0xfe/0x326
         asm_call_on_stack+0x12/0x20
         </IRQ>
         do_softirq_own_stack+0x5f/0x80
         irq_exit_rcu+0xaf/0xc0
         sysvec_apic_timer_interrupt+0x2e/0xb0
         asm_sysvec_apic_timer_interrupt+0x12/0x20
      
      This commit avoids tis problem by adding an exit hook in lock_torture_ops
      and using it to call percpu_free_rwsem() for percpu rwsem torture during
      the module-cleanup function, thus ensuring that rcu_sync_func() completes
      before module exits.
      
      It is also necessary to call the exit hook if lock_torture_init()
      fails half-way, so this commit also adds an ->init_called field in
      lock_torture_cxt to indicate that exit hook, if present, must be called.
      Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      0d720287
    • Paul E. McKenney's avatar
      locktorture: Prevent hangs for invalid arguments · 6b74fa0a
      Paul E. McKenney authored
      If an locktorture torture-test run is given a bad kvm.sh argument, the
      test will complain to the console, which is good.  What is bad is that
      from the user's perspective, it will just hang for the time specified
      by the --duration argument.  This commit therefore forces an immediate
      kernel shutdown if a lock_torture_init()-time error occurs, thus avoiding
      the appearance of a hang.  It also forces a console splat in this case
      to clearly indicate the presence of an error.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      6b74fa0a
    • Hou Tao's avatar
      locktorture: Ignore nreaders_stress if no readlock support · e5ace37d
      Hou Tao authored
      Exclusive locks do not have readlock support, which means that a
      locktorture run with the following module parameters will do nothing:
      
       torture_type=mutex_lock nwriters_stress=0 nreaders_stress=1
      
      This commit therefore rejects this combination for exclusive locks by
      returning -EINVAL during module init.
      Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      e5ace37d
    • Paul E. McKenney's avatar
      locktorture: Track time of last ->writeunlock() · 3480d677
      Paul E. McKenney authored
      This commit adds a last_lock_release variable that tracks the time of
      the last ->writeunlock() call, which allows easier diagnosing of lock
      hangs when using a kernel debugger.
      Acked-by: default avatarDavidlohr Bueso <dbueso@suse.de>
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      3480d677
  11. 25 Aug, 2020 1 commit
  12. 29 Jun, 2020 1 commit
    • Zou Wei's avatar
      locktorture: Use true and false to assign to bool variables · d02c6b52
      Zou Wei authored
      This commit fixes the following coccicheck warnings:
      
      kernel/locking/locktorture.c:689:6-10: WARNING: Assignment of 0/1 to bool variable
      kernel/locking/locktorture.c:907:2-20: WARNING: Assignment of 0/1 to bool variable
      kernel/locking/locktorture.c:938:3-20: WARNING: Assignment of 0/1 to bool variable
      kernel/locking/locktorture.c:668:2-19: WARNING: Assignment of 0/1 to bool variable
      kernel/locking/locktorture.c:674:2-19: WARNING: Assignment of 0/1 to bool variable
      kernel/locking/locktorture.c:634:2-20: WARNING: Assignment of 0/1 to bool variable
      kernel/locking/locktorture.c:640:2-20: WARNING: Assignment of 0/1 to bool variable
      Reported-by: default avatarHulk Robot <hulkci@huawei.com>
      Signed-off-by: default avatarZou Wei <zou_wei@huawei.com>
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      d02c6b52
  13. 15 Jun, 2020 1 commit
  14. 20 Feb, 2020 3 commits
    • Paul E. McKenney's avatar
      locktorture: Forgive apparent unfairness if CPU hotplug · 28e09a2e
      Paul E. McKenney authored
      If CPU hotplug testing is enabled, a lock might appear to be maximally
      unfair just because one of the CPUs was offline almost all the time.
      This commit therefore forgives unfairness if CPU hotplug testing was
      enabled.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      28e09a2e
    • Paul E. McKenney's avatar
      locktorture: Use private random-number generators · c0e1472d
      Paul E. McKenney authored
      Both lock_torture_writer() and lock_torture_reader() use the "static"
      keyword on their DEFINE_TORTURE_RANDOM(rand) declarations, which means
      that a single instance of a random-number generator are shared among all
      the writers and another is shared among all the readers.  Unfortunately,
      this random-number generator was not designed for concurrent access.
      This commit therefore removes both "static" keywords so that each reader
      and each writer gets its own random-number generator.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      c0e1472d
    • Paul E. McKenney's avatar
      locktorture: Print ratio of acquisitions, not failures · 80c503e0
      Paul E. McKenney authored
      The __torture_print_stats() function in locktorture.c carefully
      initializes local variable "min" to statp[0].n_lock_acquired, but
      then compares it to statp[i].n_lock_fail.  Given that the .n_lock_fail
      field should normally be zero, and given the initialization, it seems
      reasonable to display the maximum and minimum number acquisitions
      instead of miscomputing the maximum and minimum number of failures.
      This commit therefore switches from failures to acquisitions.
      
      And this turns out to be not only a day-zero bug, but entirely my
      own fault.  I hate it when that happens!
      
      Fixes: 0af3fe1e ("locktorture: Add a lock-torture kernel module")
      Reported-by: default avatarWill Deacon <will@kernel.org>
      Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
      Acked-by: default avatarWill Deacon <will@kernel.org>
      Cc: Davidlohr Bueso <dave@stgolabs.net>
      Cc: Josh Triplett <josh@joshtriplett.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      80c503e0
  15. 05 Oct, 2019 2 commits
  16. 28 May, 2019 1 commit
    • Paul E. McKenney's avatar
      torture: Allow inter-stutter interval to be specified · ff3bf92d
      Paul E. McKenney authored
      Currently, the inter-stutter interval is the same as the stutter duration,
      that is, whatever number of jiffies is passed into torture_stutter_init().
      This has worked well for quite some time, but the addition of
      forward-progress testing to rcutorture can delay processes for several
      seconds, which can triple the time that they are stuttered.
      
      This commit therefore adds a second argument to torture_stutter_init()
      that specifies the inter-stutter interval.  While locktorture preserves
      the current behavior, rcutorture uses the RCU CPU stall warning interval
      to provide a wider inter-stutter interval.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.ibm.com>
      ff3bf92d
  17. 26 Mar, 2019 1 commit
    • Paul E. McKenney's avatar
      locktorture: NULL cxt.lwsa and cxt.lrsa to allow bad-arg detection · a9d6938d
      Paul E. McKenney authored
      Currently, lock_torture_cleanup() uses the values of cxt.lwsa and cxt.lrsa
      to detect bad parameters that prevented locktorture from initializing,
      let alone running.  In this case, lock_torture_cleanup() does no cleanup
      aside from invoking torture_cleanup_begin() and torture_cleanup_end(),
      as required to permit future torture tests to run.  However, this
      heuristic fails if the run with bad parameters was preceded by a previous
      run that actually ran:  In this case, both cxt.lwsa and cxt.lrsa will
      remain non-zero, which means that the current lock_torture_cleanup()
      invocation will be unable to detect the fact that it should skip cleanup,
      which can result in charming outcomes such as double frees.
      
      This commit therefore NULLs out both cxt.lwsa and cxt.lrsa at the end
      of any run that actually ran.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.ibm.com>
      Cc: Davidlohr Bueso <dave@stgolabs.net>
      Cc: Josh Triplett <josh@joshtriplett.org>
      a9d6938d
  18. 09 Feb, 2019 1 commit
  19. 25 Jan, 2019 1 commit
  20. 03 Jul, 2018 1 commit
    • Thomas Hellstrom's avatar
      locking: Implement an algorithm choice for Wound-Wait mutexes · 08295b3b
      Thomas Hellstrom authored
      The current Wound-Wait mutex algorithm is actually not Wound-Wait but
      Wait-Die. Implement also Wound-Wait as a per-ww-class choice. Wound-Wait
      is, contrary to Wait-Die a preemptive algorithm and is known to generate
      fewer backoffs. Testing reveals that this is true if the
      number of simultaneous contending transactions is small.
      As the number of simultaneous contending threads increases, Wait-Wound
      becomes inferior to Wait-Die in terms of elapsed time.
      Possibly due to the larger number of held locks of sleeping transactions.
      
      Update documentation and callers.
      
      Timings using git://people.freedesktop.org/~thomash/ww_mutex_test
      tag patch-18-06-15
      
      Each thread runs 100000 batches of lock / unlock 800 ww mutexes randomly
      chosen out of 100000. Four core Intel x86_64:
      
      Algorithm    #threads       Rollbacks  time
      Wound-Wait   4              ~100       ~17s.
      Wait-Die     4              ~150000    ~19s.
      Wound-Wait   16             ~360000    ~109s.
      Wait-Die     16             ~450000    ~82s.
      
      Cc: Ingo Molnar <mingo@redhat.com>
      Cc: Jonathan Corbet <corbet@lwn.net>
      Cc: Gustavo Padovan <gustavo@padovan.org>
      Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
      Cc: Sean Paul <seanpaul@chromium.org>
      Cc: David Airlie <airlied@linux.ie>
      Cc: Davidlohr Bueso <dave@stgolabs.net>
      Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
      Cc: Josh Triplett <josh@joshtriplett.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Kate Stewart <kstewart@linuxfoundation.org>
      Cc: Philippe Ombredanne <pombredanne@nexb.com>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: linux-doc@vger.kernel.org
      Cc: linux-media@vger.kernel.org
      Cc: linaro-mm-sig@lists.linaro.org
      Co-authored-by: default avatarPeter Zijlstra <peterz@infradead.org>
      Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
      Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Acked-by: default avatarIngo Molnar <mingo@kernel.org>
      08295b3b
  21. 25 Jun, 2018 2 commits
    • Paul E. McKenney's avatar
      torture: Keep old-school dmesg format · 60500037
      Paul E. McKenney authored
      This commit adds "#define pr_fmt(fmt) fmt" to the torture-test files
      in order to keep the current dmesg format.  Once Joe's commits have
      hit mainline, these definitions will be changed in order to automatically
      generate the dmesg line prefix that the scripts expect.  This will have
      the beneficial side-effect of allowing printk() formats to be used more
      widely and of shortening some pr_*() lines.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
      Cc: Joe Perches <joe@perches.com>
      60500037
    • Paul E. McKenney's avatar
      torture: Make online/offline messages appear only for verbose=2 · 90127d60
      Paul E. McKenney authored
      Some bugs reproduce quickly only at high CPU-hotplug rates, so the
      rcutorture TREE03 scenario now has only 200 milliseconds spacing between
      CPU-hotplug operations.  At this rate, the torture-test pair of console
      messages per operation becomes a bit voluminous.  This commit therefore
      converts the torture-test set of "verbose" kernel-boot arguments from
      bool to int, and prints the extra console messages only when verbose=2.
      The default is still verbose=1.
      Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
      90127d60
  22. 12 Jun, 2018 2 commits
    • Kees Cook's avatar
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook authored
      The kzalloc() function has a 2-factor argument form, kcalloc(). This
      patch replaces cases of:
      
              kzalloc(a * b, gfp)
      
      with:
              kcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kzalloc(a * b * c, gfp)
      
      with:
      
              kzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kzalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc
      + kcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(sizeof(THING) * C2, ...)
      |
        kzalloc(sizeof(TYPE) * C2, ...)
      |
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(C1 * C2, ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      6396bb22
    • Kees Cook's avatar
      treewide: kmalloc() -> kmalloc_array() · 6da2ec56
      Kees Cook authored
      The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
      patch replaces cases of:
      
              kmalloc(a * b, gfp)
      
      with:
              kmalloc_array(a * b, gfp)
      
      as well as handling cases of:
      
              kmalloc(a * b * c, gfp)
      
      with:
      
              kmalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kmalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kmalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The tools/ directory was manually excluded, since it has its own
      implementation of kmalloc().
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kmalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kmalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kmalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kmalloc
      + kmalloc_array
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kmalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(sizeof(THING) * C2, ...)
      |
        kmalloc(sizeof(TYPE) * C2, ...)
      |
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(C1 * C2, ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      6da2ec56
  23. 11 Dec, 2017 2 commits