* [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp
@ 2022-12-14 12:06 Uladzislau Rezki (Sony)
2022-12-14 12:06 ` [PATCH 2/2] rcu/kvfree: Split ready for reclaim objects from a batch Uladzislau Rezki (Sony)
2022-12-15 20:40 ` [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp Paul E. McKenney
0 siblings, 2 replies; 5+ messages in thread
From: Uladzislau Rezki (Sony) @ 2022-12-14 12:06 UTC (permalink / raw)
To: LKML, RCU, Paul E . McKenney
Cc: Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Uladzislau Rezki, Oleksiy Avramchenko
Problem. A schedule_delayed_monitor_work() relays on the
number of pointers queued into krcp. Based on that number
and threshold the work is rearmed with different delayed
intervals, i.e. sooner or later.
There are three pipes where pointers can be placed. When
any pipe is offloaded the krcp->count counter is set to
zero - what is wrong. Because another pipes might not be
empty.
Fix it by maintaining a counter individually per a pipe.
In order to get a number of objects per a krcp introduce
a krc_count() helper.
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
kernel/rcu/tree.c | 40 ++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index d155f2594317..312cb0dee117 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2785,7 +2785,8 @@ struct kfree_rcu_cpu_work {
* @lock: Synchronize access to this structure
* @monitor_work: Promote @head to @head_free after KFREE_DRAIN_JIFFIES
* @initialized: The @rcu_work fields have been initialized
- * @count: Number of objects for which GP not started
+ * @head_count: Number of objects in rcu_head singular list
+ * @bulk_count: Number of objects in bulk-list
* @bkvcache:
* A simple cache list that contains objects for reuse purpose.
* In order to save some per-cpu space the list is singular.
@@ -2803,13 +2804,19 @@ struct kfree_rcu_cpu_work {
* the interactions with the slab allocators.
*/
struct kfree_rcu_cpu {
+ // Objects queued on a linked list
+ // through their rcu_head structures.
struct rcu_head *head;
+ atomic_t head_count;
+
+ // Objects queued on a bulk-list.
struct list_head bulk_head[FREE_N_CHANNELS];
+ atomic_t bulk_count[FREE_N_CHANNELS];
+
struct kfree_rcu_cpu_work krw_arr[KFREE_N_BATCHES];
raw_spinlock_t lock;
struct delayed_work monitor_work;
bool initialized;
- int count;
struct delayed_work page_cache_work;
atomic_t backoff_page_cache_fill;
@@ -3032,12 +3039,23 @@ need_offload_krc(struct kfree_rcu_cpu *krcp)
return !!READ_ONCE(krcp->head);
}
+static int krc_count(struct kfree_rcu_cpu *krcp)
+{
+ int sum = atomic_read(&krcp->head_count);
+ int i;
+
+ for (i = 0; i < FREE_N_CHANNELS; i++)
+ sum += atomic_read(&krcp->bulk_count[i]);
+
+ return sum;
+}
+
static void
schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
{
long delay, delay_left;
- delay = READ_ONCE(krcp->count) >= KVFREE_BULK_MAX_ENTR ? 1:KFREE_DRAIN_JIFFIES;
+ delay = krc_count(krcp) >= KVFREE_BULK_MAX_ENTR ? 1:KFREE_DRAIN_JIFFIES;
if (delayed_work_pending(&krcp->monitor_work)) {
delay_left = krcp->monitor_work.timer.expires - jiffies;
if (delay < delay_left)
@@ -3075,8 +3093,10 @@ static void kfree_rcu_monitor(struct work_struct *work)
// Channel 1 corresponds to the SLAB-pointer bulk path.
// Channel 2 corresponds to vmalloc-pointer bulk path.
for (j = 0; j < FREE_N_CHANNELS; j++) {
- if (list_empty(&krwp->bulk_head_free[j]))
+ if (list_empty(&krwp->bulk_head_free[j])) {
list_replace_init(&krcp->bulk_head[j], &krwp->bulk_head_free[j]);
+ atomic_set(&krcp->bulk_count[j], 0);
+ }
}
// Channel 3 corresponds to both SLAB and vmalloc
@@ -3084,6 +3104,7 @@ static void kfree_rcu_monitor(struct work_struct *work)
if (!krwp->head_free) {
krwp->head_free = krcp->head;
WRITE_ONCE(krcp->head, NULL);
+ atomic_set(&krcp->head_count, 0);
// Take a snapshot for this krwp. Please note no more
// any objects can be added to attached head_free channel
@@ -3091,8 +3112,6 @@ static void kfree_rcu_monitor(struct work_struct *work)
krwp->head_free_gp_snap = get_state_synchronize_rcu();
}
- WRITE_ONCE(krcp->count, 0);
-
// One work is per one batch, so there are three
// "free channels", the batch can handle. It can
// be that the work is in the pending state when
@@ -3229,6 +3248,8 @@ add_ptr_to_bulk_krc_lock(struct kfree_rcu_cpu **krcp,
// Finally insert and update the GP for this page.
bnode->records[bnode->nr_records++] = ptr;
bnode->gp_snap = get_state_synchronize_rcu();
+ atomic_inc(&(*krcp)->bulk_count[idx]);
+
return true;
}
@@ -3282,11 +3303,10 @@ void kvfree_call_rcu(struct rcu_head *head, void *ptr)
head->func = ptr;
head->next = krcp->head;
WRITE_ONCE(krcp->head, head);
+ atomic_inc(&krcp->head_count);
success = true;
}
- WRITE_ONCE(krcp->count, krcp->count + 1);
-
// Set timer to drain after KFREE_DRAIN_JIFFIES.
if (rcu_scheduler_active == RCU_SCHEDULER_RUNNING)
schedule_delayed_monitor_work(krcp);
@@ -3317,7 +3337,7 @@ kfree_rcu_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
for_each_possible_cpu(cpu) {
struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
- count += READ_ONCE(krcp->count);
+ count += krc_count(krcp);
count += READ_ONCE(krcp->nr_bkv_objs);
atomic_set(&krcp->backoff_page_cache_fill, 1);
}
@@ -3334,7 +3354,7 @@ kfree_rcu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
int count;
struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
- count = krcp->count;
+ count = krc_count(krcp);
count += drain_page_cache(krcp);
kfree_rcu_monitor(&krcp->monitor_work.work);
--
2.30.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] rcu/kvfree: Split ready for reclaim objects from a batch
2022-12-14 12:06 [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp Uladzislau Rezki (Sony)
@ 2022-12-14 12:06 ` Uladzislau Rezki (Sony)
2022-12-15 20:40 ` [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp Paul E. McKenney
1 sibling, 0 replies; 5+ messages in thread
From: Uladzislau Rezki (Sony) @ 2022-12-14 12:06 UTC (permalink / raw)
To: LKML, RCU, Paul E . McKenney
Cc: Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Uladzislau Rezki, Oleksiy Avramchenko
This patch splits ready to free pointers from the ones which
require an extra grace period. This is done before submitting
a new batch.
Once a split is done, ready to free are released right away
and after that a new batch is queued from the monitor work
over a queue_rcu_work().
Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
---
kernel/rcu/tree.c | 87 +++++++++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 33 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 312cb0dee117..50a585caf698 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2764,15 +2764,13 @@ struct kvfree_rcu_bulk_data {
* struct kfree_rcu_cpu_work - single batch of kfree_rcu() requests
* @rcu_work: Let queue_rcu_work() invoke workqueue handler after grace period
* @head_free: List of kfree_rcu() objects waiting for a grace period
- * @head_free_gp_snap: Snapshot of RCU state for objects placed to "@head_free"
* @bulk_head_free: Bulk-List of kvfree_rcu() objects waiting for a grace period
* @krcp: Pointer to @kfree_rcu_cpu structure
*/
struct kfree_rcu_cpu_work {
- struct work_struct rcu_work;
+ struct rcu_work rcu_work;
struct rcu_head *head_free;
- unsigned long head_free_gp_snap;
struct list_head bulk_head_free[FREE_N_CHANNELS];
struct kfree_rcu_cpu *krcp;
};
@@ -2780,6 +2778,7 @@ struct kfree_rcu_cpu_work {
/**
* struct kfree_rcu_cpu - batch up kfree_rcu() requests for RCU grace period
* @head: List of kfree_rcu() objects not yet waiting for a grace period
+ * @head_gp_snap: Snapshot of RCU state for objects placed to "@head"
* @bulk_head: Bulk-List of kvfree_rcu() objects not yet waiting for a grace period
* @krw_arr: Array of batches of kfree_rcu() objects waiting for a grace period
* @lock: Synchronize access to this structure
@@ -2807,6 +2806,7 @@ struct kfree_rcu_cpu {
// Objects queued on a linked list
// through their rcu_head structures.
struct rcu_head *head;
+ unsigned long head_gp_snap;
atomic_t head_count;
// Objects queued on a bulk-list.
@@ -2975,10 +2975,9 @@ static void kfree_rcu_work(struct work_struct *work)
struct rcu_head *head;
struct kfree_rcu_cpu *krcp;
struct kfree_rcu_cpu_work *krwp;
- unsigned long head_free_gp_snap;
int i;
- krwp = container_of(work,
+ krwp = container_of(to_rcu_work(work),
struct kfree_rcu_cpu_work, rcu_work);
krcp = krwp->krcp;
@@ -2990,26 +2989,11 @@ static void kfree_rcu_work(struct work_struct *work)
// Channel 3.
head = krwp->head_free;
krwp->head_free = NULL;
- head_free_gp_snap = krwp->head_free_gp_snap;
raw_spin_unlock_irqrestore(&krcp->lock, flags);
// Handle the first two channels.
for (i = 0; i < FREE_N_CHANNELS; i++) {
// Start from the tail page, so a GP is likely passed for it.
- list_for_each_entry_safe_reverse(bnode, n, &bulk_head[i], list) {
- // Not yet ready? Bail out since we need one more GP.
- if (!poll_state_synchronize_rcu(bnode->gp_snap))
- break;
-
- list_del_init(&bnode->list);
- kvfree_rcu_bulk(krcp, bnode, i);
- }
-
- // Please note a request for one more extra GP can
- // occur only once for all objects in this batch.
- if (!list_empty(&bulk_head[i]))
- synchronize_rcu();
-
list_for_each_entry_safe(bnode, n, &bulk_head[i], list)
kvfree_rcu_bulk(krcp, bnode, i);
}
@@ -3021,10 +3005,7 @@ static void kfree_rcu_work(struct work_struct *work)
* queued on a linked list through their rcu_head structures.
* This list is named "Channel 3".
*/
- if (head) {
- cond_synchronize_rcu(head_free_gp_snap);
- kvfree_rcu_list(head);
- }
+ kvfree_rcu_list(head);
}
static bool
@@ -3065,6 +3046,44 @@ schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
queue_delayed_work(system_wq, &krcp->monitor_work, delay);
}
+static void
+kvfree_rcu_drain_ready(struct kfree_rcu_cpu *krcp)
+{
+ struct list_head bulk_ready[FREE_N_CHANNELS];
+ struct kvfree_rcu_bulk_data *bnode, *n;
+ struct rcu_head *head_ready = NULL;
+ unsigned long flags;
+ int i;
+
+ raw_spin_lock_irqsave(&krcp->lock, flags);
+ for (i = 0; i < FREE_N_CHANNELS; i++) {
+ INIT_LIST_HEAD(&bulk_ready[i]);
+
+ list_for_each_entry_safe_reverse(bnode, n, &krcp->bulk_head[i], list) {
+ if (!poll_state_synchronize_rcu(bnode->gp_snap))
+ break;
+
+ atomic_sub(bnode->nr_records, &krcp->bulk_count[i]);
+ list_move(&bnode->list, &bulk_ready[i]);
+ }
+ }
+
+ if (krcp->head && poll_state_synchronize_rcu(krcp->head_gp_snap)) {
+ head_ready = krcp->head;
+ atomic_set(&krcp->head_count, 0);
+ WRITE_ONCE(krcp->head, NULL);
+ }
+ raw_spin_unlock_irqrestore(&krcp->lock, flags);
+
+ for (i = 0; i < FREE_N_CHANNELS; i++) {
+ list_for_each_entry_safe(bnode, n, &bulk_ready[i], list)
+ kvfree_rcu_bulk(krcp, bnode, i);
+ }
+
+ if (head_ready)
+ kvfree_rcu_list(head_ready);
+}
+
/*
* This function is invoked after the KFREE_DRAIN_JIFFIES timeout.
*/
@@ -3075,6 +3094,9 @@ static void kfree_rcu_monitor(struct work_struct *work)
unsigned long flags;
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.
@@ -3094,8 +3116,9 @@ static void kfree_rcu_monitor(struct work_struct *work)
// Channel 2 corresponds to vmalloc-pointer bulk path.
for (j = 0; j < FREE_N_CHANNELS; j++) {
if (list_empty(&krwp->bulk_head_free[j])) {
- list_replace_init(&krcp->bulk_head[j], &krwp->bulk_head_free[j]);
atomic_set(&krcp->bulk_count[j], 0);
+ list_replace_init(&krcp->bulk_head[j],
+ &krwp->bulk_head_free[j]);
}
}
@@ -3103,13 +3126,8 @@ static void kfree_rcu_monitor(struct work_struct *work)
// objects queued on the linked list.
if (!krwp->head_free) {
krwp->head_free = krcp->head;
- WRITE_ONCE(krcp->head, NULL);
atomic_set(&krcp->head_count, 0);
-
- // Take a snapshot for this krwp. Please note no more
- // any objects can be added to attached head_free channel
- // therefore fixate a GP for it here.
- krwp->head_free_gp_snap = get_state_synchronize_rcu();
+ WRITE_ONCE(krcp->head, NULL);
}
// One work is per one batch, so there are three
@@ -3117,7 +3135,7 @@ 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_work(system_wq, &krwp->rcu_work);
+ queue_rcu_work(system_wq, &krwp->rcu_work);
}
}
@@ -3304,6 +3322,9 @@ void kvfree_call_rcu(struct rcu_head *head, void *ptr)
head->next = krcp->head;
WRITE_ONCE(krcp->head, head);
atomic_inc(&krcp->head_count);
+
+ // Take a snapshot for this krcp.
+ krcp->head_gp_snap = get_state_synchronize_rcu();
success = true;
}
@@ -4860,7 +4881,7 @@ static void __init kfree_rcu_batch_init(void)
struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
for (i = 0; i < KFREE_N_BATCHES; i++) {
- INIT_WORK(&krcp->krw_arr[i].rcu_work, kfree_rcu_work);
+ INIT_RCU_WORK(&krcp->krw_arr[i].rcu_work, kfree_rcu_work);
krcp->krw_arr[i].krcp = krcp;
for (j = 0; j < FREE_N_CHANNELS; j++)
--
2.30.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp
2022-12-14 12:06 [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp Uladzislau Rezki (Sony)
2022-12-14 12:06 ` [PATCH 2/2] rcu/kvfree: Split ready for reclaim objects from a batch Uladzislau Rezki (Sony)
@ 2022-12-15 20:40 ` Paul E. McKenney
2022-12-15 21:16 ` Uladzislau Rezki
1 sibling, 1 reply; 5+ messages in thread
From: Paul E. McKenney @ 2022-12-15 20:40 UTC (permalink / raw)
To: Uladzislau Rezki (Sony)
Cc: LKML, RCU, Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Oleksiy Avramchenko
On Wed, Dec 14, 2022 at 01:06:29PM +0100, Uladzislau Rezki (Sony) wrote:
> Problem. A schedule_delayed_monitor_work() relays on the
> number of pointers queued into krcp. Based on that number
> and threshold the work is rearmed with different delayed
> intervals, i.e. sooner or later.
>
> There are three pipes where pointers can be placed. When
> any pipe is offloaded the krcp->count counter is set to
> zero - what is wrong. Because another pipes might not be
> empty.
>
> Fix it by maintaining a counter individually per a pipe.
> In order to get a number of objects per a krcp introduce
> a krc_count() helper.
>
> Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
Queued and pushed for further review and testing, and with the usual
wordsmithing. Much better use of workqueue handlers, thank you!!!
Thanx, Paul
> ---
> kernel/rcu/tree.c | 40 ++++++++++++++++++++++++++++++----------
> 1 file changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index d155f2594317..312cb0dee117 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -2785,7 +2785,8 @@ struct kfree_rcu_cpu_work {
> * @lock: Synchronize access to this structure
> * @monitor_work: Promote @head to @head_free after KFREE_DRAIN_JIFFIES
> * @initialized: The @rcu_work fields have been initialized
> - * @count: Number of objects for which GP not started
> + * @head_count: Number of objects in rcu_head singular list
> + * @bulk_count: Number of objects in bulk-list
> * @bkvcache:
> * A simple cache list that contains objects for reuse purpose.
> * In order to save some per-cpu space the list is singular.
> @@ -2803,13 +2804,19 @@ struct kfree_rcu_cpu_work {
> * the interactions with the slab allocators.
> */
> struct kfree_rcu_cpu {
> + // Objects queued on a linked list
> + // through their rcu_head structures.
> struct rcu_head *head;
> + atomic_t head_count;
> +
> + // Objects queued on a bulk-list.
> struct list_head bulk_head[FREE_N_CHANNELS];
> + atomic_t bulk_count[FREE_N_CHANNELS];
> +
> struct kfree_rcu_cpu_work krw_arr[KFREE_N_BATCHES];
> raw_spinlock_t lock;
> struct delayed_work monitor_work;
> bool initialized;
> - int count;
>
> struct delayed_work page_cache_work;
> atomic_t backoff_page_cache_fill;
> @@ -3032,12 +3039,23 @@ need_offload_krc(struct kfree_rcu_cpu *krcp)
> return !!READ_ONCE(krcp->head);
> }
>
> +static int krc_count(struct kfree_rcu_cpu *krcp)
> +{
> + int sum = atomic_read(&krcp->head_count);
> + int i;
> +
> + for (i = 0; i < FREE_N_CHANNELS; i++)
> + sum += atomic_read(&krcp->bulk_count[i]);
> +
> + return sum;
> +}
> +
> static void
> schedule_delayed_monitor_work(struct kfree_rcu_cpu *krcp)
> {
> long delay, delay_left;
>
> - delay = READ_ONCE(krcp->count) >= KVFREE_BULK_MAX_ENTR ? 1:KFREE_DRAIN_JIFFIES;
> + delay = krc_count(krcp) >= KVFREE_BULK_MAX_ENTR ? 1:KFREE_DRAIN_JIFFIES;
> if (delayed_work_pending(&krcp->monitor_work)) {
> delay_left = krcp->monitor_work.timer.expires - jiffies;
> if (delay < delay_left)
> @@ -3075,8 +3093,10 @@ static void kfree_rcu_monitor(struct work_struct *work)
> // Channel 1 corresponds to the SLAB-pointer bulk path.
> // Channel 2 corresponds to vmalloc-pointer bulk path.
> for (j = 0; j < FREE_N_CHANNELS; j++) {
> - if (list_empty(&krwp->bulk_head_free[j]))
> + if (list_empty(&krwp->bulk_head_free[j])) {
> list_replace_init(&krcp->bulk_head[j], &krwp->bulk_head_free[j]);
> + atomic_set(&krcp->bulk_count[j], 0);
> + }
> }
>
> // Channel 3 corresponds to both SLAB and vmalloc
> @@ -3084,6 +3104,7 @@ static void kfree_rcu_monitor(struct work_struct *work)
> if (!krwp->head_free) {
> krwp->head_free = krcp->head;
> WRITE_ONCE(krcp->head, NULL);
> + atomic_set(&krcp->head_count, 0);
>
> // Take a snapshot for this krwp. Please note no more
> // any objects can be added to attached head_free channel
> @@ -3091,8 +3112,6 @@ static void kfree_rcu_monitor(struct work_struct *work)
> krwp->head_free_gp_snap = get_state_synchronize_rcu();
> }
>
> - WRITE_ONCE(krcp->count, 0);
> -
> // One work is per one batch, so there are three
> // "free channels", the batch can handle. It can
> // be that the work is in the pending state when
> @@ -3229,6 +3248,8 @@ add_ptr_to_bulk_krc_lock(struct kfree_rcu_cpu **krcp,
> // Finally insert and update the GP for this page.
> bnode->records[bnode->nr_records++] = ptr;
> bnode->gp_snap = get_state_synchronize_rcu();
> + atomic_inc(&(*krcp)->bulk_count[idx]);
> +
> return true;
> }
>
> @@ -3282,11 +3303,10 @@ void kvfree_call_rcu(struct rcu_head *head, void *ptr)
> head->func = ptr;
> head->next = krcp->head;
> WRITE_ONCE(krcp->head, head);
> + atomic_inc(&krcp->head_count);
> success = true;
> }
>
> - WRITE_ONCE(krcp->count, krcp->count + 1);
> -
> // Set timer to drain after KFREE_DRAIN_JIFFIES.
> if (rcu_scheduler_active == RCU_SCHEDULER_RUNNING)
> schedule_delayed_monitor_work(krcp);
> @@ -3317,7 +3337,7 @@ kfree_rcu_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
> for_each_possible_cpu(cpu) {
> struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
>
> - count += READ_ONCE(krcp->count);
> + count += krc_count(krcp);
> count += READ_ONCE(krcp->nr_bkv_objs);
> atomic_set(&krcp->backoff_page_cache_fill, 1);
> }
> @@ -3334,7 +3354,7 @@ kfree_rcu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
> int count;
> struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
>
> - count = krcp->count;
> + count = krc_count(krcp);
> count += drain_page_cache(krcp);
> kfree_rcu_monitor(&krcp->monitor_work.work);
>
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp
2022-12-15 20:40 ` [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp Paul E. McKenney
@ 2022-12-15 21:16 ` Uladzislau Rezki
2022-12-15 21:33 ` Paul E. McKenney
0 siblings, 1 reply; 5+ messages in thread
From: Uladzislau Rezki @ 2022-12-15 21:16 UTC (permalink / raw)
To: Paul E. McKenney
Cc: Uladzislau Rezki (Sony), LKML, RCU, Frederic Weisbecker,
Neeraj Upadhyay, Joel Fernandes, Oleksiy Avramchenko
On Thu, Dec 15, 2022 at 12:40:22PM -0800, Paul E. McKenney wrote:
> On Wed, Dec 14, 2022 at 01:06:29PM +0100, Uladzislau Rezki (Sony) wrote:
> > Problem. A schedule_delayed_monitor_work() relays on the
> > number of pointers queued into krcp. Based on that number
> > and threshold the work is rearmed with different delayed
> > intervals, i.e. sooner or later.
> >
> > There are three pipes where pointers can be placed. When
> > any pipe is offloaded the krcp->count counter is set to
> > zero - what is wrong. Because another pipes might not be
> > empty.
> >
> > Fix it by maintaining a counter individually per a pipe.
> > In order to get a number of objects per a krcp introduce
> > a krc_count() helper.
> >
> > Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
>
> Queued and pushed for further review and testing, and with the usual
> wordsmithing. Much better use of workqueue handlers, thank you!!!
>
<snip>
This commit therefore maintains per-pipe counters, and introduces a a
krc_count() helper to access the aggregate value of those
counters.
<snip>
a a ? :)
--
Uladzislau Rezki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp
2022-12-15 21:16 ` Uladzislau Rezki
@ 2022-12-15 21:33 ` Paul E. McKenney
0 siblings, 0 replies; 5+ messages in thread
From: Paul E. McKenney @ 2022-12-15 21:33 UTC (permalink / raw)
To: Uladzislau Rezki
Cc: LKML, RCU, Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Oleksiy Avramchenko
On Thu, Dec 15, 2022 at 10:16:15PM +0100, Uladzislau Rezki wrote:
> On Thu, Dec 15, 2022 at 12:40:22PM -0800, Paul E. McKenney wrote:
> > On Wed, Dec 14, 2022 at 01:06:29PM +0100, Uladzislau Rezki (Sony) wrote:
> > > Problem. A schedule_delayed_monitor_work() relays on the
> > > number of pointers queued into krcp. Based on that number
> > > and threshold the work is rearmed with different delayed
> > > intervals, i.e. sooner or later.
> > >
> > > There are three pipes where pointers can be placed. When
> > > any pipe is offloaded the krcp->count counter is set to
> > > zero - what is wrong. Because another pipes might not be
> > > empty.
> > >
> > > Fix it by maintaining a counter individually per a pipe.
> > > In order to get a number of objects per a krcp introduce
> > > a krc_count() helper.
> > >
> > > Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
> >
> > Queued and pushed for further review and testing, and with the usual
> > wordsmithing. Much better use of workqueue handlers, thank you!!!
> >
> <snip>
> This commit therefore maintains per-pipe counters, and introduces a a
> krc_count() helper to access the aggregate value of those
> counters.
> <snip>
>
> a a ? :)
Good eyes! I will fix on my next rebase.
Thanx, Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-12-15 21:33 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-14 12:06 [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp Uladzislau Rezki (Sony)
2022-12-14 12:06 ` [PATCH 2/2] rcu/kvfree: Split ready for reclaim objects from a batch Uladzislau Rezki (Sony)
2022-12-15 20:40 ` [PATCH 1/2] rcu/kvfree: Carefully reset number of objects in krcp Paul E. McKenney
2022-12-15 21:16 ` Uladzislau Rezki
2022-12-15 21:33 ` Paul E. McKenney
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.