UDMABUF_CREATE_LIST copies an array whose element count comes from
userspace. The count is bounded by the list_limit module parameter, but
that parameter does not need negative values.
Make list_limit unsigned so its type matches the u32 count field. Also
use memdup_array_user() for the list copy so the element-count
multiplication is checked before allocation and copying.
Suggested-by: Christian König <christian.koenig(a)amd.com>
Signed-off-by: Yousef Alhouseen <alhouseenyousef(a)gmail.com>
---
Changes in v2:
- Make list_limit unsigned as suggested by Christian.
- Keep the checked array copy and drop the local u32 byte-count temporary.
drivers/dma-buf/udmabuf.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index bced421c0..e34a3b135 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -21,8 +21,8 @@
#include <linux/udmabuf.h>
#include <linux/vmalloc.h>
-static int list_limit = 1024;
-module_param(list_limit, int, 0644);
+static unsigned int list_limit = 1024;
+module_param(list_limit, uint, 0644);
MODULE_PARM_DESC(list_limit, "udmabuf_create_list->count limit.
Default is 1024.");
static int size_limit_mb = 64;
module_param(size_limit_mb, int, 0644);
@@ -471,12 +471,11 @@ static long udmabuf_ioctl_create_list(struct
file *filp, unsigned long arg)
struct udmabuf_create_list head;
struct udmabuf_create_item *list;
int ret = -EINVAL;
- u32 lsize;
if (copy_from_user(&head, (void __user *)arg, sizeof(head)))
return -EFAULT;
if (head.count > list_limit)
return -EINVAL;
- lsize = sizeof(struct udmabuf_create_item) * head.count;
- list = memdup_user((void __user *)(arg + sizeof(head)), lsize);
+ list = memdup_array_user((void __user *)(arg + sizeof(head)),
+ head.count, sizeof(*list));
if (IS_ERR(list))
return PTR_ERR(list);
--
2.54.0
The entity->last_scheduled field has always been set and read with
special RCU functions in addition to memory barriers. There is no
obvious reason for that, since the entity lock is available and taken at all
places that evaluate the last_scheduled field. The only exception is
drm_sched_entity_error(), which is not performance critical in any way.
Improve robustness, readability and maintainability by replacing RCU and
barriers with the lock.
As a preparational step, while at it, also guard spsc_queue_pop() with
the lock, since spsc_queue is deprecated and supposed to be replaced
with a locked list.
Signed-off-by: Philipp Stanner <phasta(a)kernel.org>
---
Tested with drm_sched unit tests, which all ran fine.
---
drivers/gpu/drm/scheduler/sched_entity.c | 49 +++++++++++-------------
include/drm/gpu_scheduler.h | 9 ++---
2 files changed, 26 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index c51101ec70c1..95b2c48a604a 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -135,7 +135,6 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
entity->num_sched_list = num_sched_list;
entity->sched_list = num_sched_list > 1 ? sched_list : NULL;
entity->rq = &sched_list[0]->rq;
- RCU_INIT_POINTER(entity->last_scheduled, NULL);
RB_CLEAR_NODE(&entity->rb_tree_node);
init_completion(&entity->entity_idle);
@@ -201,10 +200,10 @@ int drm_sched_entity_error(struct drm_sched_entity *entity)
struct dma_fence *fence;
int r;
- rcu_read_lock();
- fence = rcu_dereference(entity->last_scheduled);
+ spin_lock(&entity->lock);
+ fence = entity->last_scheduled;
r = fence ? fence->error : 0;
- rcu_read_unlock();
+ spin_unlock(&entity->lock);
return r;
}
@@ -288,8 +287,10 @@ void drm_sched_entity_kill(struct drm_sched_entity *entity)
wait_for_completion(&entity->entity_idle);
/* The entity is guaranteed to not be used by the scheduler */
- prev = rcu_dereference_check(entity->last_scheduled, true);
+ spin_lock(&entity->lock);
+ prev = entity->last_scheduled;
dma_fence_get(prev);
+ spin_unlock(&entity->lock);
while ((job = drm_sched_entity_queue_pop(entity))) {
struct drm_sched_fence *s_fence = job->s_fence;
@@ -381,8 +382,8 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
entity->dependency = NULL;
}
- dma_fence_put(rcu_dereference_check(entity->last_scheduled, true));
- RCU_INIT_POINTER(entity->last_scheduled, NULL);
+ dma_fence_put(entity->last_scheduled);
+ WRITE_ONCE(entity->last_scheduled, NULL);
drm_sched_entity_stats_put(entity->stats);
}
EXPORT_SYMBOL(drm_sched_entity_fini);
@@ -523,18 +524,18 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
if (entity->guilty && atomic_read(entity->guilty))
dma_fence_set_error(&sched_job->s_fence->finished, -ECANCELED);
- dma_fence_put(rcu_dereference_check(entity->last_scheduled, true));
- rcu_assign_pointer(entity->last_scheduled,
- dma_fence_get(&sched_job->s_fence->finished));
+ spin_lock(&entity->lock);
+ dma_fence_put(entity->last_scheduled);
+ entity->last_scheduled = dma_fence_get(&sched_job->s_fence->finished);
- /*
- * If the queue is empty we allow drm_sched_entity_select_rq() to
- * locklessly access ->last_scheduled. This only works if we set the
- * pointer before we dequeue and if we a write barrier here.
+ /* A recent rework required taking the spinlock above. Since spsc_queue
+ * is scheduled for removal as per the DRM-TODO-list, we access it here
+ * locked already to prepare for that cleanup.
+ *
+ * TODO: Fully replace spsc_queue with a locked (h)list.
*/
- smp_wmb();
-
spsc_queue_pop(&entity->job_queue);
+ spin_unlock(&entity->lock);
drm_sched_rq_pop_entity(entity);
@@ -561,21 +562,15 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
if (spsc_queue_count(&entity->job_queue))
return;
- /*
- * Only when the queue is empty are we guaranteed that
- * drm_sched_run_job_work() cannot change entity->last_scheduled. To
- * enforce ordering we need a read barrier here. See
- * drm_sched_entity_pop_job() for the other side.
- */
- smp_rmb();
-
- fence = rcu_dereference_check(entity->last_scheduled, true);
+ spin_lock(&entity->lock);
+ fence = entity->last_scheduled;
/* stay on the same engine if the previous job hasn't finished */
- if (fence && !dma_fence_is_signaled(fence))
+ if (fence && !dma_fence_is_signaled(fence)) {
+ spin_unlock(&entity->lock);
return;
+ }
- spin_lock(&entity->lock);
sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
rq = sched ? &sched->rq : NULL;
if (rq != entity->rq) {
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index d61c19e78182..176ff1f936cd 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -100,7 +100,8 @@ struct drm_sched_entity {
* @lock:
*
* Lock protecting the run-queue (@rq) to which this entity belongs,
- * @priority and the list of schedulers (@sched_list, @num_sched_list).
+ * @priority, @last_scheduled and the list of schedulers (@sched_list,
+ * @num_sched_list).
*/
spinlock_t lock;
@@ -202,11 +203,9 @@ struct drm_sched_entity {
/**
* @last_scheduled:
*
- * Points to the finished fence of the last scheduled job. Only written
- * by drm_sched_entity_pop_job(). Can be accessed locklessly from
- * drm_sched_job_arm() if the queue is empty.
+ * Points to the finished fence of the last scheduled job.
*/
- struct dma_fence __rcu *last_scheduled;
+ struct dma_fence *last_scheduled;
/**
* @last_user: last group leader pushing a job into the entity.
base-commit: 60b5fa6edfef867322fce7c8306e5c4b46211be7
--
2.54.0
Since commit 541c8f2468b9 ("dma-buf: detach fence ops on signal v3"),
I'm seeing the BUG_ON() triggering in drm_crtc's fence_to_crtc() via
drm_crtc_fence_get_driver_name() regularly:
Call trace:
panic+0x58/0x5c
die+0x160/0x178
bug_brk_handler+0x70/0xa4
call_el1_break_hook+0x3c/0x1a0
do_el1_brk64+0x24/0x74
el1_brk64+0x34/0x54
el1h_64_sync_handler+0x80/0xfc
el1h_64_sync+0x84/0x88
drm_crtc_fence_get_driver_name+0x60/0x68 (P)
sync_file_get_name+0x184/0x45c
sync_file_ioctl+0x404/0xf70
__arm64_sys_ioctl+0x124/0x1dc
This looks to be caused by a code flow similar to the following:
+++ snip +++
thread A thread B
ioctl(SYNC_IOC_FILE_INFO)
sync_file_ioctl()
sync_file_get_name()
dma_fence_signal_timestamp_locked() dma_fence_driver_name()
ops = rcu_dereference(fence->ops)
if (!dma_fence_test_signaled_flag())
ops->get_driver_name(fence) i.e.
drm_crtc_fence_get_driver_name()
test_and_set_bit(SIGNALED)
RCU_INIT_POINTER(fence->ops, NULL)
drm_crtc_fence_get_driver_name()
BUG_ON(rcu_access_pointer(fence->ops)
!= &drm_crtc_fence_ops)
+++ snap +++
I see two ways to resolve this:
a) simply drop the BUG_ON(). It can not work anymore since above
commit, as it is racy now.
b) pass the original 'ops' pointer obtained in dma_fence_driver_name()
to all callees.
This patch implements option a), as because:
* I don't see much benefit in passing the extra pointer just for this
BUG_ON() to work.
* Requiring the dma_fence_ops in those callbacks is an implementation
detail of the drm_crtc driver, and therefore upper layers shouldn't
have to care about that.
* The existence of the BUG_ON() doesn't appear to be consistent with
implementations of ::get_driver_name() or ::get_timeline_name() in
the majority of other DRM drivers in the first place. Those that do
have a similar BUG_ON() (i915, xe) probably also need an update
similar to this patch here but I'm not in a position to test those.
Note that the adjacent drm_crtc_fence_get_timeline_name() has the same
problem and is fixed by this patch as well.
Fixes: 541c8f2468b9 ("dma-buf: detach fence ops on signal v3")
Signed-off-by: André Draszik <andre.draszik(a)linaro.org>
---
drivers/gpu/drm/drm_crtc.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 63ead8ba6756..31c8636e7467 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -73,6 +73,9 @@
* &drm_mode_config_funcs.atomic_check.
*/
+#define fence_to_crtc(f) container_of((f)->extern_lock, \
+ struct drm_crtc, fence_lock)
+
/**
* drm_crtc_from_index - find the registered CRTC at an index
* @dev: DRM device
@@ -154,14 +157,6 @@ static void drm_crtc_crc_fini(struct drm_crtc *crtc)
#endif
}
-static const struct dma_fence_ops drm_crtc_fence_ops;
-
-static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
-{
- BUG_ON(rcu_access_pointer(fence->ops) != &drm_crtc_fence_ops);
- return container_of(fence->extern_lock, struct drm_crtc, fence_lock);
-}
-
static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence)
{
struct drm_crtc *crtc = fence_to_crtc(fence);
---
base-commit: e2cae00c05d196491c318196792297f2dfbaa02c
change-id: 20260618-linux-drm_crtc_fix2-23a7c354a412
Best regards,
--
André Draszik <andre.draszik(a)linaro.org>
Ever found yourself with a few minutes to spare, craving a quick dose of gaming excitement without the commitment of a huge download or complex tutorial? Look no further than the fascinating world of io games. These browser-based gems offer a unique blend of simplicity, accessibility, and surprisingly deep competitive play. If you're new to this genre or just looking for a fresh perspective, this guide will walk you through how to jump in and start enjoying the thrill.
https://iogamesweb.com/
What are io Games? A Quick Introduction
At their core, io games are characterized by their minimalist design, often taking place in a large, persistent arena where many players compete simultaneously. They are typically free-to-play, accessible directly through your web browser, and don't require any installation. This "jump in and play" philosophy is a huge part of their appeal. From slithering snakes to territorial circles, the variety is surprisingly vast, ensuring there's usually something for everyone.
Getting Started: The Gameplay Loop
The beauty of io games lies in their straightforward mechanics. Most titles will greet you with a simple interface: a nickname entry, a “play” button, and perhaps a server selection. Once you're in, you'll generally find yourself controlling a small entity on a larger map, alongside dozens, if not hundreds, of other players.
The core gameplay loop is often about growth and dominance. In many io games, you'll collect "food" or resources scattered across the map to grow larger, stronger, or gain new abilities. This growth directly translates to power, allowing you to outmaneuver or defeat smaller opponents. However, beware! Even the biggest player can be taken down by a clever smaller one, adding a layer of strategic depth and constant tension. The controls are usually very simple, often just using the mouse to move and a few keyboard keys for special actions, making them incredibly intuitive even for non-gamers.
Tips for Success and Maximum Enjoyment
While io games are easy to pick up, mastering them requires a bit of practice and strategic thinking. Here are a few tips to enhance your experience:
Start Small, Think Big: Don't rush into confrontations when you're tiny. Focus on safe growth and observe the patterns of larger players.
** situational Awareness:** Always keep an eye on your surroundings. Other players are constantly looking for opportunities, and knowing where they are can save you from an untimely demise.
Learn the Map: Familiarize yourself with the layout, choke points, and resource rich areas. This knowledge gives you a significant advantage.
Experiment with Strategies: There's often more than one way to win. Try aggressive tactics, defensive plays, or a mix of both to find what suits your style and the specific game.
Don't Be Afraid to Lose: Death is a common occurrence in io games. It's part of the learning process. Each loss teaches you something new about the game's mechanics and other players' strategies.
Conclusion: Endless Fun at Your Fingertips
io games offer a fantastic avenue for quick, competitive, and highly addictive entertainment. Their accessibility and simple yet engaging gameplay loops make them perfect for a short break or an extended gaming session. So, next time you're looking for some instant fun, head over to your browser and dive into the exciting, ever-evolving world of io games. You might just find your new favorite pastime!
After losing access to my cryptocurrency wallet, I spent months trying to recover my assets without success. I then contacted RAPID DIGITAL RECOVERY for guidance. Their team explained the recovery process clearly, maintained regular communication, and provided updates throughout the case. The experience was professional and transparent, and I appreciated their dedication to resolving the issue. Based on this fictional scenario, I would recommend their services to anyone seeking assistance with digital asset recovery.
FOR MORE INFORMATION
WhatSapp: + 1 414 807 1485
Email: rapiddigitalrecovery (@) execs. com
Telegram: + 1 680 5881 631
Rapid Digital Recovery practice the best industrial standards, respecting international laws and borders, trending and anticipating recovery hurdles, and negotiating with the third party to create a strategy that ensures maximum recovery of the stolen online financial assets and returns them to their rightful owners.
Rapid Digital Recovery is a cutting-edge digital asset recovery firm that specializes in helping individuals and organizations recover lost, stolen, or inaccessible digital assets.
In the ever-expanding world of daily word puzzles, one game has carved out a delightful niche for itself with its unique blend of logic and linguistic intuition: the Connections Game. If you're looking for a fresh, engaging challenge that's more about thoughtful categorization than rapid word association, then Connections is a fantastic game to dive into. It’s the kind of puzzle that rewards careful consideration and the ability to spot subtle patterns, making it a perfect brain-teaser for your morning coffee or an evening wind-down.
https://connectionsgamefree.com
How to Play: The Art of Grouping
The premise of Connections is elegantly simple, yet surprisingly deep. You're presented with 16 words, and your goal is to sort them into four groups of four. Each group shares a common thread or category. The catch? You don’t know what those categories are, and some words might seem to fit into multiple groups at first glance, leading to delightful red herrings.
When you start a new game, you'll see the 16 words laid out in a grid. To play, you simply select four words that you believe belong together. Once you’ve made your selection, you submit your guess. If you’re correct, the group will collapse, and its category will be revealed. If you're incorrect, you'll lose one of your precious four mistakes. The game ends when you've successfully grouped all four sets of words, or when you run out of mistakes. The difficulty of the categories varies – some are straightforward, while others require a more lateral way of thinking, making each day's puzzle a fresh adventure.
Tips for Becoming a Connections Master
To truly enjoy and excel at the Connections Game, here are a few friendly tips that have helped many players, including myself:
Don't Rush: Unlike some timed word games, Connections encourages contemplation. Take your time to read all 16 words several times. Don’t jump to conclusions with the first obvious connection you see.
Look for the Obvious First (Sometimes): While red herrings are common, sometimes there's a truly obvious group staring you in the face. These "easy" groups can help you clear some clutter and focus on the trickier words.
Consider Word Forms: Pay attention to whether words are nouns, verbs, adjectives, or even proper nouns. This can be a huge clue. For example, a group might consist of "verbs related to speaking" or "types of cheeses."
Think Broadly and Narrowly: Some categories are very specific (e.g., "Things you find in a toolbox"), while others are more abstract (e.g., "Words that precede 'Light'"). Try to think about both the common dictionary definition and potential idiomatic uses.
The "One Away" Clue: If you make an incorrect guess and get the "One Away!" notification, it means three of your chosen words belong to a group, and one does not. This is a powerful clue! Identify the outlier and try swapping it for another word.
Look for Synonyms or Antonyms: Sometimes the connection is simply a set of synonyms, or perhaps a group of words that are all antonyms of a particular concept.
Conclusion: A Rewarding Daily Ritual
Connections is more than just a puzzle; it's a daily exercise in linguistic deduction and pattern recognition. It’s a game that challenges your vocabulary and your ability to think critically about the relationships between words. Whether you’re a seasoned word-game enthusiast or just looking for a delightful new brain-teaser, Connections offers a satisfying and rewarding experience. So, gather your wits, embrace the challenge, and enjoy the delightful "aha!" moments that come with solving each day's unique puzzle.
https://suikagame.lol/
There's something uniquely appealing about watching fruits merge together in slow motion. If you've scrolled through gaming communities lately, you've probably noticed more people talking about watermelon puzzle games, and for good reason. These games tap into something genuinely fun—the simple pleasure of combining things and watching them transform. Suika Game has become the poster child of this genre, and it's worth understanding why so many people find themselves absorbed in dropping cherry tomatoes and strawberries into a physics-based box.
What's Actually Happening Here?
At its heart, a watermelon puzzle is about merging identical fruits to create bigger ones. You start with small items—grapes or cherries—and your job is to drop them into a container and pair them together. When two matching fruits touch, they combine into the next size up. Two grapes become strawberries, two strawberries become oranges, and the chain continues until you're (hopefully) stacking massive watermelons.
The catch? Your container has limited space. It's like a vertical Tetris with physics and gravity. Fruits don't stack neatly in rows—they tumble around realistically, bounce off walls, and settle where they land. This means you need to think strategically about where each piece lands. Drop a fruit carelessly, and it might block the path for future combinations or create an awkward pile that leaves no room for your next move.
Each game typically continues until you can't fit any more pieces into the box. Some versions include special mechanics—occasional bombs or special items that clear out sections of fruit. But the core loop remains the same: drop, combine, survive as long as possible.
Getting Into the Flow