summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2021-08-12 16:08:47 +0300
committerMichael Bestas <mkbestas@lineageos.org>2021-08-12 16:08:47 +0300
commit31f7e9ca68c764f84eef4f7a077aa078c2b25007 (patch)
treee1a022c2c54f95456b7969b2bade0adfd69a0477 /kernel
parente5c348556ec23d17f1f91f838a9c45509ad6c0bc (diff)
parentafefb5a03546b25a00c89366a837de8d5dc12704 (diff)
Merge remote-tracking branch 'msm8998/lineage-18.1' into lineage-18.1
Change-Id: I838feeb8dc3d47071e2b49a1e489154ace948fb4
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/fair.c4
-rw-r--r--kernel/trace/ring_buffer.c28
-rw-r--r--kernel/workqueue.c20
3 files changed, 39 insertions, 13 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 78bd960c3527..51443a801af5 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5509,7 +5509,7 @@ static const u64 cfs_bandwidth_slack_period = 5 * NSEC_PER_MSEC;
static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
{
struct hrtimer *refresh_timer = &cfs_b->period_timer;
- u64 remaining;
+ s64 remaining;
/* if the call-back is running a quota refresh is already occurring */
if (hrtimer_callback_running(refresh_timer))
@@ -5517,7 +5517,7 @@ static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
/* is a quota refresh about to occur? */
remaining = ktime_to_ns(hrtimer_expires_remaining(refresh_timer));
- if (remaining < min_expire)
+ if (remaining < (s64)min_expire)
return 1;
return 0;
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 1ec760f6bf58..19b30ff90cc4 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -3086,10 +3086,30 @@ static bool rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
if (unlikely(!head))
return true;
- return reader->read == rb_page_commit(reader) &&
- (commit == reader ||
- (commit == head &&
- head->read == rb_page_commit(commit)));
+ /* Reader should exhaust content in reader page */
+ if (reader->read != rb_page_commit(reader))
+ return false;
+
+ /*
+ * If writers are committing on the reader page, knowing all
+ * committed content has been read, the ring buffer is empty.
+ */
+ if (commit == reader)
+ return true;
+
+ /*
+ * If writers are committing on a page other than reader page
+ * and head page, there should always be content to read.
+ */
+ if (commit != head)
+ return false;
+
+ /*
+ * Writers are committing on the head page, we just need
+ * to care about there're committed data, and the reader will
+ * swap reader page with head page when it is to read data.
+ */
+ return rb_page_commit(commit) == 0;
}
/**
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 478411ce98e6..46efb8ed5224 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3343,15 +3343,21 @@ static void pwq_unbound_release_workfn(struct work_struct *work)
unbound_release_work);
struct workqueue_struct *wq = pwq->wq;
struct worker_pool *pool = pwq->pool;
- bool is_last;
+ bool is_last = false;
- if (WARN_ON_ONCE(!(wq->flags & WQ_UNBOUND)))
- return;
+ /*
+ * when @pwq is not linked, it doesn't hold any reference to the
+ * @wq, and @wq is invalid to access.
+ */
+ if (!list_empty(&pwq->pwqs_node)) {
+ if (WARN_ON_ONCE(!(wq->flags & WQ_UNBOUND)))
+ return;
- mutex_lock(&wq->mutex);
- list_del_rcu(&pwq->pwqs_node);
- is_last = list_empty(&wq->pwqs);
- mutex_unlock(&wq->mutex);
+ mutex_lock(&wq->mutex);
+ list_del_rcu(&pwq->pwqs_node);
+ is_last = list_empty(&wq->pwqs);
+ mutex_unlock(&wq->mutex);
+ }
mutex_lock(&wq_pool_mutex);
put_unbound_pool(pool);