Merge 4a39ac5b7d ("Merge tag 'random-6.12-rc1-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random") into android-mainline
Steps on the way to 6.12-rc1 Bug: 367265496 Change-Id: I115d487c6294c249dd30b708b3164f34be34d874 Signed-off-by: Matthias Maennich <maennich@google.com>
This commit is contained in:
+101
-8
@@ -3564,18 +3564,15 @@ kvfree_rcu_drain_ready(struct kfree_rcu_cpu *krcp)
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is invoked after the KFREE_DRAIN_JIFFIES timeout.
|
||||
* Return: %true if a work is queued, %false otherwise.
|
||||
*/
|
||||
static void kfree_rcu_monitor(struct work_struct *work)
|
||||
static bool
|
||||
kvfree_rcu_queue_batch(struct kfree_rcu_cpu *krcp)
|
||||
{
|
||||
struct kfree_rcu_cpu *krcp = container_of(work,
|
||||
struct kfree_rcu_cpu, monitor_work.work);
|
||||
unsigned long flags;
|
||||
bool queued = false;
|
||||
int i, j;
|
||||
|
||||
// Drain ready for reclaim.
|
||||
kvfree_rcu_drain_ready(krcp);
|
||||
|
||||
raw_spin_lock_irqsave(&krcp->lock, flags);
|
||||
|
||||
// Attempt to start a new batch.
|
||||
@@ -3614,11 +3611,27 @@ static void kfree_rcu_monitor(struct work_struct *work)
|
||||
// be that the work is in the pending state when
|
||||
// channels have been detached following by each
|
||||
// other.
|
||||
queue_rcu_work(system_unbound_wq, &krwp->rcu_work);
|
||||
queued = queue_rcu_work(system_unbound_wq, &krwp->rcu_work);
|
||||
}
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&krcp->lock, flags);
|
||||
return queued;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is invoked after the KFREE_DRAIN_JIFFIES timeout.
|
||||
*/
|
||||
static void kfree_rcu_monitor(struct work_struct *work)
|
||||
{
|
||||
struct kfree_rcu_cpu *krcp = container_of(work,
|
||||
struct kfree_rcu_cpu, monitor_work.work);
|
||||
|
||||
// Drain ready for reclaim.
|
||||
kvfree_rcu_drain_ready(krcp);
|
||||
|
||||
// Queue a batch for a rest.
|
||||
kvfree_rcu_queue_batch(krcp);
|
||||
|
||||
// If there is nothing to detach, it means that our job is
|
||||
// successfully done here. In case of having at least one
|
||||
@@ -3840,6 +3853,86 @@ unlock_return:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvfree_call_rcu);
|
||||
|
||||
/**
|
||||
* kvfree_rcu_barrier - Wait until all in-flight kvfree_rcu() complete.
|
||||
*
|
||||
* Note that a single argument of kvfree_rcu() call has a slow path that
|
||||
* triggers synchronize_rcu() following by freeing a pointer. It is done
|
||||
* before the return from the function. Therefore for any single-argument
|
||||
* call that will result in a kfree() to a cache that is to be destroyed
|
||||
* during module exit, it is developer's responsibility to ensure that all
|
||||
* such calls have returned before the call to kmem_cache_destroy().
|
||||
*/
|
||||
void kvfree_rcu_barrier(void)
|
||||
{
|
||||
struct kfree_rcu_cpu_work *krwp;
|
||||
struct kfree_rcu_cpu *krcp;
|
||||
bool queued;
|
||||
int i, cpu;
|
||||
|
||||
/*
|
||||
* Firstly we detach objects and queue them over an RCU-batch
|
||||
* for all CPUs. Finally queued works are flushed for each CPU.
|
||||
*
|
||||
* Please note. If there are outstanding batches for a particular
|
||||
* CPU, those have to be finished first following by queuing a new.
|
||||
*/
|
||||
for_each_possible_cpu(cpu) {
|
||||
krcp = per_cpu_ptr(&krc, cpu);
|
||||
|
||||
/*
|
||||
* Check if this CPU has any objects which have been queued for a
|
||||
* new GP completion. If not(means nothing to detach), we are done
|
||||
* with it. If any batch is pending/running for this "krcp", below
|
||||
* per-cpu flush_rcu_work() waits its completion(see last step).
|
||||
*/
|
||||
if (!need_offload_krc(krcp))
|
||||
continue;
|
||||
|
||||
while (1) {
|
||||
/*
|
||||
* If we are not able to queue a new RCU work it means:
|
||||
* - batches for this CPU are still in flight which should
|
||||
* be flushed first and then repeat;
|
||||
* - no objects to detach, because of concurrency.
|
||||
*/
|
||||
queued = kvfree_rcu_queue_batch(krcp);
|
||||
|
||||
/*
|
||||
* Bail out, if there is no need to offload this "krcp"
|
||||
* anymore. As noted earlier it can run concurrently.
|
||||
*/
|
||||
if (queued || !need_offload_krc(krcp))
|
||||
break;
|
||||
|
||||
/* There are ongoing batches. */
|
||||
for (i = 0; i < KFREE_N_BATCHES; i++) {
|
||||
krwp = &(krcp->krw_arr[i]);
|
||||
flush_rcu_work(&krwp->rcu_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we guarantee that all objects are flushed.
|
||||
*/
|
||||
for_each_possible_cpu(cpu) {
|
||||
krcp = per_cpu_ptr(&krc, cpu);
|
||||
|
||||
/*
|
||||
* A monitor work can drain ready to reclaim objects
|
||||
* directly. Wait its completion if running or pending.
|
||||
*/
|
||||
cancel_delayed_work_sync(&krcp->monitor_work);
|
||||
|
||||
for (i = 0; i < KFREE_N_BATCHES; i++) {
|
||||
krwp = &(krcp->krw_arr[i]);
|
||||
flush_rcu_work(&krwp->rcu_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvfree_rcu_barrier);
|
||||
|
||||
static unsigned long
|
||||
kfree_rcu_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user