24 Feb, 2020

1 commit

  • [ Upstream commit 894c9ef9780c5cf2f143415e867ee39a33ecb75d ]

    Configuring an instance's parallel mask without any online CPUs...

    echo 2 > /sys/kernel/pcrypt/pencrypt/parallel_cpumask
    echo 0 > /sys/devices/system/cpu/cpu1/online

    ...makes tcrypt mode=215 crash like this:

    divide error: 0000 [#1] SMP PTI
    CPU: 4 PID: 283 Comm: modprobe Not tainted 5.4.0-rc8-padata-doc-v2+ #2
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20191013_105130-anatol 04/01/2014
    RIP: 0010:padata_do_parallel+0x114/0x300
    Call Trace:
    pcrypt_aead_encrypt+0xc0/0xd0 [pcrypt]
    crypto_aead_encrypt+0x1f/0x30
    do_mult_aead_op+0x4e/0xdf [tcrypt]
    test_mb_aead_speed.constprop.0.cold+0x226/0x564 [tcrypt]
    do_test+0x28c2/0x4d49 [tcrypt]
    tcrypt_mod_init+0x55/0x1000 [tcrypt]
    ...

    cpumask_weight() in padata_cpu_hash() returns 0 because the mask has no
    CPUs. The problem is __padata_remove_cpu() checks for valid masks too
    early and so doesn't mark the instance PADATA_INVALID as expected, which
    would have made padata_do_parallel() return error before doing the
    division.

    Fix by introducing a second padata CPU hotplug state before
    CPUHP_BRINGUP_CPU so that __padata_remove_cpu() sees the online mask
    without @cpu. No need for the second argument to padata_replace() since
    @cpu is now already missing from the online mask.

    Fixes: 33e54450683c ("padata: Handle empty padata cpumasks")
    Signed-off-by: Daniel Jordan
    Cc: Eric Biggers
    Cc: Herbert Xu
    Cc: Sebastian Andrzej Siewior
    Cc: Steffen Klassert
    Cc: Thomas Gleixner
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu
    Signed-off-by: Sasha Levin

    Daniel Jordan
     

11 Feb, 2020

2 commits

  • commit bbefa1dd6a6d53537c11624752219e39959d04fb upstream.

    If the pcrypt template is used multiple times in an algorithm, then a
    deadlock occurs because all pcrypt instances share the same
    padata_instance, which completes requests in the order submitted. That
    is, the inner pcrypt request waits for the outer pcrypt request while
    the outer request is already waiting for the inner.

    This patch fixes this by allocating a set of queues for each pcrypt
    instance instead of using two global queues. In order to maintain
    the existing user-space interface, the pinst structure remains global
    so any sysfs modifications will apply to every pcrypt instance.

    Note that when an update occurs we have to allocate memory for
    every pcrypt instance. Should one of the allocations fail we
    will abort the update without rolling back changes already made.

    The new per-instance data structure is called padata_shell and is
    essentially a wrapper around parallel_data.

    Reproducer:

    #include
    #include
    #include

    int main()
    {
    struct sockaddr_alg addr = {
    .salg_type = "aead",
    .salg_name = "pcrypt(pcrypt(rfc4106-gcm-aesni))"
    };
    int algfd, reqfd;
    char buf[32] = { 0 };

    algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
    bind(algfd, (void *)&addr, sizeof(addr));
    setsockopt(algfd, SOL_ALG, ALG_SET_KEY, buf, 20);
    reqfd = accept(algfd, 0, 0);
    write(reqfd, buf, 32);
    read(reqfd, buf, 16);
    }

    Reported-by: syzbot+56c7151cad94eec37c521f0e47d2eee53f9361c4@syzkaller.appspotmail.com
    Fixes: 5068c7a883d1 ("crypto: pcrypt - Add pcrypt crypto parallelization wrapper")
    Signed-off-by: Herbert Xu
    Tested-by: Eric Biggers
    Signed-off-by: Herbert Xu
    Signed-off-by: Greg Kroah-Hartman

    Herbert Xu
     
  • commit 07928d9bfc81640bab36f5190e8725894d93b659 upstream.

    The function padata_flush_queues is fundamentally broken because
    it cannot force padata users to complete the request that is
    underway. IOW padata has to passively wait for the completion
    of any outstanding work.

    As it stands flushing is used in two places. Its use in padata_stop
    is simply unnecessary because nothing depends on the queues to
    be flushed afterwards.

    The other use in padata_replace is more substantial as we depend
    on it to free the old pd structure. This patch instead uses the
    pd->refcnt to dynamically free the pd structure once all requests
    are complete.

    Fixes: 2b73b07ab8a4 ("padata: Flush the padata queues actively")
    Cc:
    Signed-off-by: Herbert Xu
    Reviewed-by: Daniel Jordan
    Signed-off-by: Herbert Xu
    Signed-off-by: Greg Kroah-Hartman

    Herbert Xu
     

13 Sep, 2019

6 commits

  • With the removal of the ENODATA case from padata_get_next, the cpu_index
    field is no longer useful, so it can go away.

    Signed-off-by: Daniel Jordan
    Acked-by: Steffen Klassert
    Cc: Herbert Xu
    Cc: Lai Jiangshan
    Cc: Peter Zijlstra
    Cc: Tejun Heo
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     
  • Padata binds the parallel part of a job to a single CPU and round-robins
    over all CPUs in the system for each successive job. Though the serial
    parts rely on per-CPU queues for correct ordering, they're not necessary
    for parallel work, and it improves performance to run the job locally on
    NUMA machines and let the scheduler pick the CPU within a node on a busy
    system.

    So, make the parallel workqueue unbound.

    Update the parallel workqueue's cpumask when the instance's parallel
    cpumask changes.

    Now that parallel jobs no longer run on max_active=1 workqueues, two or
    more parallel works that hash to the same CPU may run simultaneously,
    finish out of order, and so be serialized out of order. Prevent this by
    keeping the works sorted on the reorder list by sequence number and
    checking that in the reordering logic.

    padata_get_next becomes padata_find_next so it can be reused for the end
    of padata_reorder, where it's used to avoid uselessly queueing work when
    the next job by sequence number isn't finished yet but a later job that
    hashed to the same CPU has.

    The ENODATA case in padata_find_next no longer makes sense because
    parallel jobs aren't bound to specific CPUs. The EINPROGRESS case takes
    care of the scenario where a parallel job is potentially running on the
    same CPU as padata_find_next, and with only one error code left, just
    use NULL instead.

    Signed-off-by: Daniel Jordan
    Cc: Herbert Xu
    Cc: Lai Jiangshan
    Cc: Peter Zijlstra
    Cc: Steffen Klassert
    Cc: Tejun Heo
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     
  • padata currently uses one per-CPU workqueue per instance for all work.

    Prepare for running parallel jobs on an unbound workqueue by introducing
    dedicated workqueues for parallel and serial work.

    Signed-off-by: Daniel Jordan
    Acked-by: Steffen Klassert
    Cc: Herbert Xu
    Cc: Lai Jiangshan
    Cc: Peter Zijlstra
    Cc: Tejun Heo
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     
  • With pcrypt's cpumask no longer used, take the CPU hotplug lock inside
    padata_alloc_possible.

    Useful later in the series for avoiding nested acquisition of the CPU
    hotplug lock in padata when padata_alloc_possible is allocating an
    unbound workqueue.

    Without this patch, this nested acquisition would happen later in the
    series:

    pcrypt_init_padata
    get_online_cpus
    alloc_padata_possible
    alloc_padata
    alloc_workqueue(WQ_UNBOUND) // later in the series
    alloc_and_link_pwqs
    apply_wqattrs_lock
    get_online_cpus // recursive rwsem acquisition

    Signed-off-by: Daniel Jordan
    Acked-by: Steffen Klassert
    Cc: Herbert Xu
    Cc: Lai Jiangshan
    Cc: Peter Zijlstra
    Cc: Tejun Heo
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     
  • padata_do_parallel currently returns -EINVAL if the callback CPU isn't
    in the callback cpumask.

    pcrypt tries to prevent this situation by keeping its own callback
    cpumask in sync with padata's and checks that the callback CPU it passes
    to padata is valid. Make padata handle this instead.

    padata_do_parallel now takes a pointer to the callback CPU and updates
    it for the caller if an alternate CPU is used. Overall behavior in
    terms of which callback CPUs are chosen stays the same.

    Prepares for removal of the padata cpumask notifier in pcrypt, which
    will fix a lockdep complaint about nested acquisition of the CPU hotplug
    lock later in the series.

    Signed-off-by: Daniel Jordan
    Acked-by: Steffen Klassert
    Cc: Herbert Xu
    Cc: Lai Jiangshan
    Cc: Peter Zijlstra
    Cc: Tejun Heo
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     
  • Move workqueue allocation inside of padata to prepare for further
    changes to how padata uses workqueues.

    Guarantees the workqueue is created with max_active=1, which padata
    relies on to work correctly. No functional change.

    Signed-off-by: Daniel Jordan
    Acked-by: Steffen Klassert
    Cc: Herbert Xu
    Cc: Jonathan Corbet
    Cc: Lai Jiangshan
    Cc: Peter Zijlstra
    Cc: Tejun Heo
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-doc@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     

09 Aug, 2019

1 commit

  • Exercising CPU hotplug on a 5.2 kernel with recent padata fixes from
    cryptodev-2.6.git in an 8-CPU kvm guest...

    # modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3
    # echo 0 > /sys/devices/system/cpu/cpu1/online
    # echo c > /sys/kernel/pcrypt/pencrypt/parallel_cpumask
    # modprobe tcrypt mode=215

    ...caused the following crash:

    BUG: kernel NULL pointer dereference, address: 0000000000000000
    #PF: supervisor read access in kernel mode
    #PF: error_code(0x0000) - not-present page
    PGD 0 P4D 0
    Oops: 0000 [#1] SMP PTI
    CPU: 2 PID: 134 Comm: kworker/2:2 Not tainted 5.2.0-padata-base+ #7
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-
    Workqueue: pencrypt padata_parallel_worker
    RIP: 0010:padata_reorder+0xcb/0x180
    ...
    Call Trace:
    padata_do_serial+0x57/0x60
    pcrypt_aead_enc+0x3a/0x50 [pcrypt]
    padata_parallel_worker+0x9b/0xe0
    process_one_work+0x1b5/0x3f0
    worker_thread+0x4a/0x3c0
    ...

    In padata_alloc_pd, pd->cpu is set using the user-supplied cpumask
    instead of the effective cpumask, and in this case cpumask_first picked
    an offline CPU.

    The offline CPU's reorder->list.next is NULL in padata_reorder because
    the list wasn't initialized in padata_init_pqueues, which only operates
    on CPUs in the effective mask.

    Fix by using the effective mask in padata_alloc_pd.

    Fixes: 6fc4dbcf0276 ("padata: Replace delayed timer with immediate workqueue in padata_reorder")
    Signed-off-by: Daniel Jordan
    Cc: Herbert Xu
    Cc: Steffen Klassert
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     

27 Jul, 2019

2 commits

  • With the removal of the padata timer, padata_do_serial no longer
    needs special CPU handling, so remove it.

    Signed-off-by: Daniel Jordan
    Cc: Herbert Xu
    Cc: Steffen Klassert
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     
  • The function padata_reorder will use a timer when it cannot progress
    while completed jobs are outstanding (pd->reorder_objects > 0). This
    is suboptimal as if we do end up using the timer then it would have
    introduced a gratuitous delay of one second.

    In fact we can easily distinguish between whether completed jobs
    are outstanding and whether we can make progress. All we have to
    do is look at the next pqueue list.

    This patch does that by replacing pd->processed with pd->cpu so
    that the next pqueue is more accessible.

    A work queue is used instead of the original try_again to avoid
    hogging the CPU.

    Note that we don't bother removing the work queue in
    padata_flush_queues because the whole premise is broken. You
    cannot flush async crypto requests so it makes no sense to even
    try. A subsequent patch will fix it by replacing it with a ref
    counting scheme.

    Signed-off-by: Herbert Xu

    Herbert Xu
     

18 Jul, 2019

1 commit

  • Testing padata with the tcrypt module on a 5.2 kernel...

    # modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3
    # modprobe tcrypt mode=211 sec=1

    ...produces this splat:

    INFO: task modprobe:10075 blocked for more than 120 seconds.
    Not tainted 5.2.0-base+ #16
    modprobe D 0 10075 10064 0x80004080
    Call Trace:
    ? __schedule+0x4dd/0x610
    ? ring_buffer_unlock_commit+0x23/0x100
    schedule+0x6c/0x90
    schedule_timeout+0x3b/0x320
    ? trace_buffer_unlock_commit_regs+0x4f/0x1f0
    wait_for_common+0x160/0x1a0
    ? wake_up_q+0x80/0x80
    { crypto_wait_req } # entries in braces added by hand
    { do_one_aead_op }
    { test_aead_jiffies }
    test_aead_speed.constprop.17+0x681/0xf30 [tcrypt]
    do_test+0x4053/0x6a2b [tcrypt]
    ? 0xffffffffa00f4000
    tcrypt_mod_init+0x50/0x1000 [tcrypt]
    ...

    The second modprobe command never finishes because in padata_reorder,
    CPU0's load of reorder_objects is executed before the unlocking store in
    spin_unlock_bh(pd->lock), causing CPU0 to miss CPU1's increment:

    CPU0 CPU1

    padata_reorder padata_do_serial
    LOAD reorder_objects // 0
    INC reorder_objects // 1
    padata_reorder
    TRYLOCK pd->lock // failed
    UNLOCK pd->lock

    CPU0 deletes the timer before returning from padata_reorder and since no
    other job is submitted to padata, modprobe waits indefinitely.

    Add a pair of full barriers to guarantee proper ordering:

    CPU0 CPU1

    padata_reorder padata_do_serial
    UNLOCK pd->lock
    smp_mb()
    LOAD reorder_objects
    INC reorder_objects
    smp_mb__after_atomic()
    padata_reorder
    TRYLOCK pd->lock

    smp_mb__after_atomic is needed so the read part of the trylock operation
    comes after the INC, as Andrea points out. Thanks also to Andrea for
    help with writing a litmus test.

    Fixes: 16295bec6398 ("padata: Generic parallelization/serialization interface")
    Signed-off-by: Daniel Jordan
    Cc:
    Cc: Andrea Parri
    Cc: Boqun Feng
    Cc: Herbert Xu
    Cc: Paul E. McKenney
    Cc: Peter Zijlstra
    Cc: Steffen Klassert
    Cc: linux-arch@vger.kernel.org
    Cc: linux-crypto@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Herbert Xu

    Daniel Jordan
     

26 Apr, 2019

1 commit

  • The kobj_type default_attrs field is being replaced by the
    default_groups field. Replace padata_attr_type's default_attrs field
    with default_groups and use the ATTRIBUTE_GROUPS macro to create
    padata_default_groups.

    This patch was tested by loading the pcrypt module and verifying that
    the sysfs files for the attributes in the default groups were created.

    Signed-off-by: Kimberly Brown
    Signed-off-by: Greg Kroah-Hartman

    Kimberly Brown
     

16 Nov, 2018

1 commit


05 Jan, 2018

1 commit


22 Nov, 2017

1 commit

  • This converts all remaining cases of the old setup_timer() API into using
    timer_setup(), where the callback argument is the structure already
    holding the struct timer_list. These should have no behavioral changes,
    since they just change which pointer is passed into the callback with
    the same available pointers after conversion. It handles the following
    examples, in addition to some other variations.

    Casting from unsigned long:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, ptr);

    and forced object casts:

    void my_callback(struct something *ptr)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr);

    become:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    Direct function assignments:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    ptr->my_timer.function = my_callback;

    have a temporary cast added, along with converting the args:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback;

    And finally, callbacks without a data assignment:

    void my_callback(unsigned long data)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, 0);

    have their argument renamed to verify they're unused during conversion:

    void my_callback(struct timer_list *unused)
    {
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    The conversion is done with the following Coccinelle script:

    spatch --very-quiet --all-includes --include-headers \
    -I ./arch/x86/include -I ./arch/x86/include/generated \
    -I ./include -I ./arch/x86/include/uapi \
    -I ./arch/x86/include/generated/uapi -I ./include/uapi \
    -I ./include/generated/uapi --include ./include/linux/kconfig.h \
    --dir . \
    --cocci-file ~/src/data/timer_setup.cocci

    @fix_address_of@
    expression e;
    @@

    setup_timer(
    -&(e)
    +&e
    , ...)

    // Update any raw setup_timer() usages that have a NULL callback, but
    // would otherwise match change_timer_function_usage, since the latter
    // will update all function assignments done in the face of a NULL
    // function initialization in setup_timer().
    @change_timer_function_usage_NULL@
    expression _E;
    identifier _timer;
    type _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, NULL, _E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E->_timer, NULL, (_cast_data)_E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, &_E);
    +timer_setup(&_E._timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, (_cast_data)&_E);
    +timer_setup(&_E._timer, NULL, 0);
    )

    @change_timer_function_usage@
    expression _E;
    identifier _timer;
    struct timer_list _stl;
    identifier _callback;
    type _cast_func, _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, _callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    _E->_timer@_stl.function = _callback;
    |
    _E->_timer@_stl.function = &_callback;
    |
    _E->_timer@_stl.function = (_cast_func)_callback;
    |
    _E->_timer@_stl.function = (_cast_func)&_callback;
    |
    _E._timer@_stl.function = _callback;
    |
    _E._timer@_stl.function = &_callback;
    |
    _E._timer@_stl.function = (_cast_func)_callback;
    |
    _E._timer@_stl.function = (_cast_func)&_callback;
    )

    // callback(unsigned long arg)
    @change_callback_handle_cast
    depends on change_timer_function_usage@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    (
    ... when != _origarg
    _handletype *_handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    )
    }

    // callback(unsigned long arg) without existing variable
    @change_callback_handle_cast_no_arg
    depends on change_timer_function_usage &&
    !change_callback_handle_cast@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    + _handletype *_origarg = from_timer(_origarg, t, _timer);
    +
    ... when != _origarg
    - (_handletype *)_origarg
    + _origarg
    ... when != _origarg
    }

    // Avoid already converted callbacks.
    @match_callback_converted
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    { ... }

    // callback(struct something *handle)
    @change_callback_handle_arg
    depends on change_timer_function_usage &&
    !match_callback_converted &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_handletype *_handle
    +struct timer_list *t
    )
    {
    + _handletype *_handle = from_timer(_handle, t, _timer);
    ...
    }

    // If change_callback_handle_arg ran on an empty function, remove
    // the added handler.
    @unchange_callback_handle_arg
    depends on change_timer_function_usage &&
    change_callback_handle_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    {
    - _handletype *_handle = from_timer(_handle, t, _timer);
    }

    // We only want to refactor the setup_timer() data argument if we've found
    // the matching callback. This undoes changes in change_timer_function_usage.
    @unchange_timer_function_usage
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg &&
    !change_callback_handle_arg@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type change_timer_function_usage._cast_data;
    @@

    (
    -timer_setup(&_E->_timer, _callback, 0);
    +setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    |
    -timer_setup(&_E._timer, _callback, 0);
    +setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    )

    // If we fixed a callback from a .function assignment, fix the
    // assignment cast now.
    @change_timer_function_assignment
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_func;
    typedef TIMER_FUNC_TYPE;
    @@

    (
    _E->_timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -&_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    )

    // Sometimes timer functions are called directly. Replace matched args.
    @change_timer_function_calls
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression _E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_data;
    @@

    _callback(
    (
    -(_cast_data)_E
    +&_E->_timer
    |
    -(_cast_data)&_E
    +&_E._timer
    |
    -_E
    +&_E->_timer
    )
    )

    // If a timer has been configured without a data argument, it can be
    // converted without regard to the callback argument, since it is unused.
    @match_timer_function_unused_data@
    expression _E;
    identifier _timer;
    identifier _callback;
    @@

    (
    -setup_timer(&_E->_timer, _callback, 0);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0L);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0UL);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0L);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0UL);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0L);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0UL);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0L);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0UL);
    +timer_setup(_timer, _callback, 0);
    )

    @change_callback_unused_data
    depends on match_timer_function_unused_data@
    identifier match_timer_function_unused_data._callback;
    type _origtype;
    identifier _origarg;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *unused
    )
    {
    ... when != _origarg
    }

    Signed-off-by: Kees Cook

    Kees Cook
     

07 Oct, 2017

3 commits

  • If the algorithm we're parallelizing is asynchronous we might change
    CPUs between padata_do_parallel() and padata_do_serial(). However, we
    don't expect this to happen as we need to enqueue the padata object into
    the per-cpu reorder queue we took it from, i.e. the same-cpu's parallel
    queue.

    Ensure we're not switching CPUs for a given padata object by tracking
    the CPU within the padata object. If the serial callback gets called on
    the wrong CPU, defer invoking padata_reorder() via a kernel worker on
    the CPU we're expected to run on.

    Signed-off-by: Mathias Krause
    Signed-off-by: Herbert Xu

    Mathias Krause
     
  • The reorder timer function runs on the CPU where the timer interrupt was
    handled which is not necessarily one of the CPUs of the 'pcpu' CPU mask
    set.

    Ensure the padata_reorder() callback runs on the correct CPU, which is
    one in the 'pcpu' CPU mask set and, preferrably, the next expected one.
    Do so by comparing the current CPU with the expected target CPU. If they
    match, call padata_reorder() right away. If they differ, schedule a work
    item on the target CPU that does the padata_reorder() call for us.

    Signed-off-by: Mathias Krause
    Signed-off-by: Herbert Xu

    Mathias Krause
     
  • The parallel queue per-cpu data structure gets initialized only for CPUs
    in the 'pcpu' CPU mask set. This is not sufficient as the reorder timer
    may run on a different CPU and might wrongly decide it's the target CPU
    for the next reorder item as per-cpu memory gets memset(0) and we might
    be waiting for the first CPU in cpumask.pcpu, i.e. cpu_index 0.

    Make the '__this_cpu_read(pd->pqueue->cpu_index) == next_queue->cpu_index'
    compare in padata_get_next() fail in this case by initializing the
    cpu_index member of all per-cpu parallel queues. Use -1 for unused ones.

    Signed-off-by: Mathias Krause
    Signed-off-by: Herbert Xu

    Mathias Krause
     

26 May, 2017

2 commits

  • pcrypt_init_padata()
    cpus_read_lock()
    padata_alloc_possible()
    padata_alloc()
    cpus_read_lock()

    The nested call to cpus_read_lock() works with the current implementation,
    but prevents the conversion to a percpu rwsem.

    The other caller of padata_alloc_possible() is pcrypt_init_padata() which
    calls from a cpus_read_lock() protected region as well.

    Remove the cpus_read_lock() call in padata_alloc() and document the
    calling convention.

    Signed-off-by: Sebastian Andrzej Siewior
    Signed-off-by: Thomas Gleixner
    Tested-by: Paul E. McKenney
    Acked-by: Ingo Molnar
    Cc: Steffen Klassert
    Cc: Peter Zijlstra
    Cc: Steven Rostedt
    Cc: linux-crypto@vger.kernel.org
    Link: http://lkml.kernel.org/r/20170524081547.571278910@linutronix.de

    Sebastian Andrzej Siewior
     
  • No users outside of padata.c

    Signed-off-by: Thomas Gleixner
    Tested-by: Paul E. McKenney
    Acked-by: Ingo Molnar
    Cc: Steffen Klassert
    Cc: Peter Zijlstra
    Cc: Sebastian Siewior
    Cc: Steven Rostedt
    Cc: linux-crypto@vger.kernel.org
    Link: http://lkml.kernel.org/r/20170524081547.491457256@linutronix.de

    Thomas Gleixner
     

21 Apr, 2017

1 commit

  • Per Dan's static checker warning, the code that returns NULL was removed
    in 2010, so this patch updates the comments and fixes the code
    assumptions.

    Signed-off-by: Jason A. Donenfeld
    Reported-by: Dan Carpenter
    Acked-by: Steffen Klassert
    Signed-off-by: Herbert Xu

    Jason A. Donenfeld
     

10 Apr, 2017

1 commit

  • The author meant to free the variable that was just allocated, instead
    of the one that failed to be allocated, but made a simple typo. This
    patch rectifies that.

    Signed-off-by: Jason A. Donenfeld
    Cc: stable@vger.kernel.org
    Signed-off-by: Herbert Xu

    Jason A. Donenfeld
     

24 Mar, 2017

1 commit

  • Under extremely heavy uses of padata, crashes occur, and with list
    debugging turned on, this happens instead:

    [87487.298728] WARNING: CPU: 1 PID: 882 at lib/list_debug.c:33
    __list_add+0xae/0x130
    [87487.301868] list_add corruption. prev->next should be next
    (ffffb17abfc043d0), but was ffff8dba70872c80. (prev=ffff8dba70872b00).
    [87487.339011] [] dump_stack+0x68/0xa3
    [87487.342198] [] ? console_unlock+0x281/0x6d0
    [87487.345364] [] __warn+0xff/0x140
    [87487.348513] [] warn_slowpath_fmt+0x4a/0x50
    [87487.351659] [] __list_add+0xae/0x130
    [87487.354772] [] ? _raw_spin_lock+0x64/0x70
    [87487.357915] [] padata_reorder+0x1e6/0x420
    [87487.361084] [] padata_do_serial+0xa5/0x120

    padata_reorder calls list_add_tail with the list to which its adding
    locked, which seems correct:

    spin_lock(&squeue->serial.lock);
    list_add_tail(&padata->list, &squeue->serial.list);
    spin_unlock(&squeue->serial.lock);

    This therefore leaves only place where such inconsistency could occur:
    if padata->list is added at the same time on two different threads.
    This pdata pointer comes from the function call to
    padata_get_next(pd), which has in it the following block:

    next_queue = per_cpu_ptr(pd->pqueue, cpu);
    padata = NULL;
    reorder = &next_queue->reorder;
    if (!list_empty(&reorder->list)) {
    padata = list_entry(reorder->list.next,
    struct padata_priv, list);
    spin_lock(&reorder->lock);
    list_del_init(&padata->list);
    atomic_dec(&pd->reorder_objects);
    spin_unlock(&reorder->lock);

    pd->processed++;

    goto out;
    }
    out:
    return padata;

    I strongly suspect that the problem here is that two threads can race
    on reorder list. Even though the deletion is locked, call to
    list_entry is not locked, which means it's feasible that two threads
    pick up the same padata object and subsequently call list_add_tail on
    them at the same time. The fix is thus be hoist that lock outside of
    that block.

    Signed-off-by: Jason A. Donenfeld
    Acked-by: Steffen Klassert
    Signed-off-by: Herbert Xu

    Jason A. Donenfeld
     

25 Oct, 2016

1 commit

  • Remove the unused but set variable pinst in padata_parallel_worker to
    fix the following warning when building with 'W=1':

    kernel/padata.c: In function ‘padata_parallel_worker’:
    kernel/padata.c:68:26: warning: variable ‘pinst’ set but not used [-Wunused-but-set-variable]

    Also remove the now unused variable pd which is only used to set pinst.

    Signed-off-by: Tobias Klauser
    Acked-by: Steffen Klassert
    Signed-off-by: Herbert Xu

    Tobias Klauser
     

20 Sep, 2016

1 commit

  • Install the callbacks via the state machine. CPU-hotplug multinstance support
    is used with the nocalls() version. Maybe parts of padata_alloc() could be
    moved into the online callback so that we could invoke ->startup callback for
    instance and drop get_online_cpus().

    Signed-off-by: Sebastian Andrzej Siewior
    Cc: Steffen Klassert
    Cc: Peter Zijlstra
    Cc: linux-crypto@vger.kernel.org
    Cc: rt@linutronix.de
    Link: http://lkml.kernel.org/r/20160906170457.32393-14-bigeasy@linutronix.de
    Signed-off-by: Thomas Gleixner

    Sebastian Andrzej Siewior
     

20 May, 2016

2 commits

  • A recent cleanup removed some exported functions that were not used
    anywhere, which in turn exposed the fact that some other functions in
    the same file are only used in some configurations.

    We now get a warning about them when CONFIG_HOTPLUG_CPU is disabled:

    kernel/padata.c:670:12: error: '__padata_remove_cpu' defined but not used [-Werror=unused-function]
    static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
    ^~~~~~~~~~~~~~~~~~~
    kernel/padata.c:650:12: error: '__padata_add_cpu' defined but not used [-Werror=unused-function]
    static int __padata_add_cpu(struct padata_instance *pinst, int cpu)

    This rearranges the code so the __padata_remove_cpu/__padata_add_cpu
    functions are within the #ifdef that protects the code that calls them.

    [akpm@linux-foundation.org: coding-style fixes]
    Fixes: 4ba6d78c671e ("kernel/padata.c: removed unused code")
    Signed-off-by: Arnd Bergmann
    Cc: Richard Cochran
    Cc: Steffen Klassert
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arnd Bergmann
     
  • By accident I stumbled across code that has never been used. This
    driver has EXPORT_SYMBOL functions, and the only user of the code is
    pcrypt.c, but this only uses a subset of the exported symbols.

    According to 'git log -G', the functions, padata_set_cpumasks,
    padata_add_cpu, and padata_remove_cpu have never been used since they
    were first introduced. This patch removes the unused code.

    On one 64 bit build, with CRYPTO_PCRYPT built in, the text is more than
    4k smaller.

    kbuild_hp> size $KBUILD_OUTPUT/vmlinux
    text data bss dec hex filename
    10566658 4678360 1122304 16367322 f9beda vmlinux
    10561984 4678360 1122304 16362648 f9ac98 vmlinux

    On another config, 32 bit, the saving is about 0.5k bytes.

    kbuild_hp-x86> size $KBUILD_OUTPUT/vmlinux
    6012005 2409513 2785280 11206798 ab008e vmlinux
    6011491 2409513 2785280 11206284 aafe8c vmlinux

    Signed-off-by: Richard Cochran
    Cc: Steffen Klassert
    Cc: Herbert Xu
    Cc: "David S. Miller"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Richard Cochran
     

14 Feb, 2015

1 commit

  • printk and friends can now format bitmaps using '%*pb[l]'. cpumask
    and nodemask also provide cpumask_pr_args() and nodemask_pr_args()
    respectively which can be used to generate the two printf arguments
    necessary to format the specified cpu/nodemask.

    Signed-off-by: Tejun Heo
    Cc: Steffen Klassert
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Tejun Heo
     

05 Dec, 2013

1 commit

  • A kernel with enabled lockdep complains about the wrong usage of
    rcu_dereference() under a rcu_read_lock_bh() protected region.

    ===============================
    [ INFO: suspicious RCU usage. ]
    3.13.0-rc1+ #126 Not tainted
    -------------------------------
    linux/kernel/padata.c:115 suspicious rcu_dereference_check() usage!

    other info that might help us debug this:

    rcu_scheduler_active = 1, debug_locks = 1
    1 lock held by cryptomgr_test/153:
    #0: (rcu_read_lock_bh){.+....}, at: [] padata_do_parallel+0x5/0x270

    Fix that by using rcu_dereference_bh() instead.

    Signed-off-by: Mathias Krause
    Acked-by: Steffen Klassert
    Signed-off-by: Herbert Xu

    Mathias Krause
     

30 Oct, 2013

1 commit

  • Using a spinlock to atomically increase a counter sounds wrong -- we've
    atomic_t for this!

    Also move 'seq_nr' to a different cache line than 'lock' to reduce cache
    line trashing. This has the nice side effect of decreasing the size of
    struct parallel_data from 192 to 128 bytes for a x86-64 build, e.g.
    occupying only two instead of three cache lines.

    Those changes results in a 5% performance increase on an IPsec test run
    using pcrypt.

    Btw. the seq_lock spinlock was never explicitly initialized -- one more
    reason to get rid of it.

    Signed-off-by: Mathias Krause
    Acked-by: Steffen Klassert
    Signed-off-by: Herbert Xu

    Mathias Krause
     

29 Aug, 2013

2 commits


06 Dec, 2012

1 commit


29 Mar, 2012

3 commits


14 Mar, 2012

2 commits

  • When padata_do_parallel() is called from multiple cpus for the same
    padata instance, we can get object reordering on sequence number wrap
    because testing for sequence number wrap and reseting the sequence
    number must happen atomically but is implemented with two atomic
    operations. This patch fixes this by converting the sequence number
    from atomic_t to an unsigned int and protect the access with a
    spin_lock. As a side effect, we get rid of the sequence number wrap
    handling because the seqence number wraps back to null now without
    the need to do anything.

    Signed-off-by: Steffen Klassert
    Signed-off-by: Herbert Xu

    Steffen Klassert
     
  • When a padata object is queued to the serialization queue, another
    cpu might process and free the padata object. So don't dereference
    it after queueing to the serialization queue.

    Signed-off-by: Steffen Klassert
    Signed-off-by: Herbert Xu

    Steffen Klassert