iForce Hacker Recovery is widely recognized as one of the top bitcoin recovery services, known for its dedication to recovering lost or stolen bitcoins. Their recovery process uses advanced blockchain analytics and forensic techniques to help victims trace and recover their digital assets. The team, made up of experts in blockchain technology and regulatory compliance, offers personalized solutions for issues like fraud, scams, and hacking.
Homepage; https://iforcehackers.com/
Email; iforcehk(a)consultant.com
Text-whatsapp; +1 (240) 803. 37 06
As a realtor accustomed to high-value transactions, nothing prepared me for the fear of losing access to my Bitcoin wallet, which included $1 million saved for retirement. After mistakenly removing the app, discovering faulty backups, and forgetting my recovery phrase, I was frantic. I contacted iFORCE HACKER RECOVERY after receiving a suggestion from a friend. Though suspicious at first, their professionalism, compassion, clear communication, and meticulous approach convinced me. After ten long days, my wallet was completely retrieved. They not only returned my Bitcoin, but also my peace of mind and future.
Contact Information:
Website: ht tps: // iforcehackers .co m .
Email: iforcehk @ consultant .co m
WhatsApp: +1 240-803-3706
I realize how volatile and thrilling cryptocurrency can be. After joining a Telegram-based service, I made consistent profits for six months before unexpected faults deprived me of approximately $343,000. Withdrawal blunders, little help, and rising dread kept me stuck. I then discovered iForce Hacker Recovery from positive reviews. They replied swiftly, handled my issue professionally, and walked me through every step. My valuables were returned within a week, giving me back my confidence. I heartily recommend their dependable, professional aid services.
Contact Info:
Website address: htt p:// iforcehackers. co m.
Email: iforcehk @ consultant .co m
WhatsApp: +1 240 803-3706
I spent a lot of time researching ways to recover stolen Bitcoin after I unexpectedly lost $120,000 during a trade. During my search, I came across multiple testimonials and ads praising the services of iForce Hacker Recovery, so I decided to reach out. I was extremely impressed with the assistance I received. Not only did I get my $120,000 back, but my hacked social media accounts were also restored. If you ever find yourself in a similar situation, don't stress—just contact iForce Hacker Recovery. They can help you recover everything you’ve lost from hacking incidents.
Website: ht tps://iforcehackers. co m
WhatsApp: +1 240-803-3706
Email: iforcehk @ consultant. c om
iForce Hacker Recovery are seasoned cryptocurrency specialists recognized for excellence in bitcoin fraud recovery. Their team has extensive knowledge of blockchain technology and the quickly changing cryptocurrency ecosystem, and they have a track record of assisting clients in recovering lost or stolen assets. They can successfully manage complex recovery cases because of their competence. There is still hope if you have been the victim of a cryptocurrency scam because iForce Hacker Recovery is ready to assist you in regaining the money that has been lost.
Website: ht tps://iforcehackers. co m
WhatsApp: +1 240-803-3706
Email: iforcehk @ consultant. c om
Hello everyone, I wish to give my own review about iFORCE HACKER RECOVERY. I hope this message reaches the right audience. As an entrepreneur, I was eager to invest in cryptocurrency after learning about its potential to significantly increase my income. I came across someone online who promised exceptionally high returns, and because he seemed knowledgeable, I was easily convinced. After investing a substantial amount, I soon discovered that I was unable to withdraw my funds. It was all a scam. This left me in debt and caused severe damage to my business. Fortunately, I came across a pop-up about cryptocurrency recovery and cybersecurity experts. I reached out to iFORCE HACKER RECOVERY, a cybersecurity and cryptocurrency recovery company, and they successfully helped me recover my lost funds. I am incredibly grateful for their services and highly recommend them to anyone in need of cryptocurrency recovery assistance.
Website; ht tps: //iforcehackers. co m/
Email; iforcehk @ consultant. c om
Call/Text-whatsapp; +1 (240) 8033 (706)
iForce Hacker Recovery are seasoned cryptocurrency specialists recognized for excellence in bitcoin fraud recovery. Their team has extensive knowledge of blockchain technology and the quickly changing cryptocurrency ecosystem, and they have a track record of assisting clients in recovering lost or stolen assets. They can successfully manage complex recovery cases because of their competence. There is still hope if you have been the victim of a cryptocurrency scam because iForce Hacker Recovery is ready to assist you in regaining the money that has been lost.
Website: ht tps://iforcehackers. co m
WhatsApp: +1 240-803-3706
Email: iforcehk @ consultant. c om
OPTIMISTIC HACKER GAIUS is a professional crypto recovery service specializing in lost Bitcoin recovery, scammed USDT recovery, and digital asset tracing. The company uses advanced blockchain analysis and investigative techniques to track and recover stolen or inaccessible cryptocurrency. Known for clear communication and ethical practices, OPTIMISTIC HACKER GAIUS provides realistic assessments and reliable support for individuals and businesses affected by crypto-related losses.
Mail-Box: support @ optimistichackargaius. c om
WhatsApp: +44 737 674 0569
Website: optimistichackargaius. co m
On 2/11/26 11:06, Philipp Stanner wrote:
> On Tue, 2026-02-10 at 11:01 +0100, Christian König wrote:
>> At first glance it is counter intuitive to protect a constant function
>> pointer table by RCU, but this allows modules providing the function
>> table to unload by waiting for an RCU grace period.
>
> I think that someone who does not already have a deep understanding
> about dma-buf and fences will have much trouble understanding *why*
> this patch is in the log and *what it achieves*.
>
> Good commit messages are at least as important as good code. In
> drm/sched for example I've been trying so many times to figure out why
> certain hacks and changes were implemented, but all that git-blame ever
> gave me was one liners, often hinting at some driver internal work
> around ._.
How about something like this:
The fence ops of a dma_fence currently need to life as long as the dma_fence is alive.
This means that the module who originally issued a dma_fence can't unload unless all of them are freed up.
As first step to solve this issue protect the fence ops by RCU.
While it is counter intuitive to protect a constant function pointer table by RCU it allows modules to wait for an RCU grace period to make sure that nobody is executing their functions any more.
>
>>
>> v2: make one the now duplicated lockdep warnings a comment instead.
>> v3: Add more documentation to ->wait and ->release callback.
>> v4: fix typo in documentation
>> v5: rebased on drm-tip
>>
>> Signed-off-by: Christian König <christian.koenig(a)amd.com>
>> ---
>> drivers/dma-buf/dma-fence.c | 69 +++++++++++++++++++++++++------------
>> include/linux/dma-fence.h | 29 ++++++++++++++--
>> 2 files changed, 73 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
>> index e05beae6e407..de9bf18be3d4 100644
>> --- a/drivers/dma-buf/dma-fence.c
>> +++ b/drivers/dma-buf/dma-fence.c
>> @@ -522,6 +522,7 @@ EXPORT_SYMBOL(dma_fence_signal);
>> signed long
>> dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
>> {
>> + const struct dma_fence_ops *ops;
>> signed long ret;
>>
>> if (WARN_ON(timeout < 0))
>> @@ -533,15 +534,21 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
>>
>> dma_fence_enable_sw_signaling(fence);
>>
>> - if (trace_dma_fence_wait_start_enabled()) {
>
> Why can wait_start_enabled() be removed? Is that related to the life
> time decoupling or is it a separate topic?
It isn't removed, I've just removed the "if (trace_dma_fence_wait_start_enabled())" optimization which is used by the tracing subsystem as self-patching code (longer story).
The trace_dma_fence_wait_start() trace point function is still called a few lines below.
>> - rcu_read_lock();
>> - trace_dma_fence_wait_start(fence);
>> + rcu_read_lock();
>> + ops = rcu_dereference(fence->ops);
>> + trace_dma_fence_wait_start(fence);
>> + if (ops->wait) {
>> + /*
>> + * Implementing the wait ops is deprecated and not supported for
>> + * issuer independent fences, so it is ok to use the ops outside
>
> s/issuer/issuers of
Fixed.
> And how do we know that this here is an independent fence?
> What even is an "independent fence" – one with internal spinlock?
I rephrased the sentence a bit to make that more clearer:
/*
* Implementing the wait ops is deprecated and not supported for
* issuers of fences who wants them to be independent of their
* module after they signal, so it is ok to use the ops outside
* the RCU protected section.
*/
>
>> + * the RCU protected section.
>> + */
>> + rcu_read_unlock();
>> + ret = ops->wait(fence, intr, timeout);
>> + } else {
>> rcu_read_unlock();
>> - }
>> - if (fence->ops->wait)
>> - ret = fence->ops->wait(fence, intr, timeout);
>> - else
>> ret = dma_fence_default_wait(fence, intr, timeout);
>> + }
>
> The git diff here looks awkward. Do you use git format-patch --
> histogram?
Nope, what's the matter?
>> if (trace_dma_fence_wait_end_enabled()) {
>> rcu_read_lock();
>> trace_dma_fence_wait_end(fence);
>>
>> @@ -1049,7 +1067,12 @@ __dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
>> BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);
>>
>> kref_init(&fence->refcount);
>> - fence->ops = ops;
>> + /*
>> + * At first glance it is counter intuitive to protect a constant
>> + * function pointer table by RCU, but this allows modules providing the
>> + * function table to unload by waiting for an RCU grace period.
>
> Maybe add a sentence like "Fences can live longer than the module which
> issued them."
Going to use the same as the commit message here as soon as we synced up on that.
>
>> + */
>> + RCU_INIT_POINTER(fence->ops, ops);
>> INIT_LIST_HEAD(&fence->cb_list);
>> fence->lock = lock;
>> fence->context = context;
>> @@ -1129,11 +1152,12 @@ EXPORT_SYMBOL(dma_fence_init64);
>> */
>> const char __rcu *dma_fence_driver_name(struct dma_fence *fence)
>> {
>> - RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
>> - "RCU protection is required for safe access to returned string");
>> + const struct dma_fence_ops *ops;
>>
>> + /* RCU protection is required for safe access to returned string */
>> + ops = rcu_dereference(fence->ops);
>> if (!dma_fence_test_signaled_flag(fence))
>> - return (const char __rcu *)fence->ops->get_driver_name(fence);
>> + return (const char __rcu *)ops->get_driver_name(fence);
>> else
>> return (const char __rcu *)"detached-driver";
>> }
>> @@ -1161,11 +1185,12 @@ EXPORT_SYMBOL(dma_fence_driver_name);
>> */
>> const char __rcu *dma_fence_timeline_name(struct dma_fence *fence)
>> {
>> - RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
>> - "RCU protection is required for safe access to returned string");
>> + const struct dma_fence_ops *ops;
>>
>> + /* RCU protection is required for safe access to returned string */
>> + ops = rcu_dereference(fence->ops);
>> if (!dma_fence_test_signaled_flag(fence))
>> - return (const char __rcu *)fence->ops->get_driver_name(fence);
>> + return (const char __rcu *)ops->get_driver_name(fence);
>> else
>> return (const char __rcu *)"signaled-timeline";
>> }
>
> Did we make any progress in our conversation about removing those two
> functions and callbacks? They're only used by i915.
Actually they are mostly used by the trace points and debugfs, so we certainly can't remove them.
But I'm really wondering why the heck i915 is using them?
>> diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
>> index 9c4d25289239..6bf4feb0e01f 100644
>> --- a/include/linux/dma-fence.h
>> +++ b/include/linux/dma-fence.h
>> @@ -67,7 +67,7 @@ struct seq_file;
>> */
>> struct dma_fence {
>> spinlock_t *lock;
>> - const struct dma_fence_ops *ops;
>> + const struct dma_fence_ops __rcu *ops;
>> /*
>> * We clear the callback list on kref_put so that by the time we
>> * release the fence it is unused. No one should be adding to the
>> @@ -220,6 +220,10 @@ struct dma_fence_ops {
>> * timed out. Can also return other error values on custom implementations,
>> * which should be treated as if the fence is signaled. For example a hardware
>> * lockup could be reported like that.
>> + *
>> + * Implementing this callback prevents the fence from detaching after
>> + * signaling and so it is mandatory for the module providing the
>
> s/mandatory/necessary ?
Fixed.
>
>> + * dma_fence_ops to stay loaded as long as the dma_fence exists.
>> */
>> signed long (*wait)(struct dma_fence *fence,
>> bool intr, signed long timeout);
>> @@ -231,6 +235,13 @@ struct dma_fence_ops {
>> * Can be called from irq context. This callback is optional. If it is
>> * NULL, then dma_fence_free() is instead called as the default
>> * implementation.
>> + *
>> + * Implementing this callback prevents the fence from detaching after
>> + * signaling and so it is mandatory for the module providing the
>
> same
Fixed.
>
>> + * dma_fence_ops to stay loaded as long as the dma_fence exists.
>> + *
>> + * If the callback is implemented the memory backing the dma_fence
>> + * object must be freed RCU safe.
>> */
>> void (*release)(struct dma_fence *fence);
>>
>> @@ -454,13 +465,19 @@ dma_fence_test_signaled_flag(struct dma_fence *fence)
>> static inline bool
>> dma_fence_is_signaled_locked(struct dma_fence *fence)
>> {
>> + const struct dma_fence_ops *ops;
>> +
>> if (dma_fence_test_signaled_flag(fence))
>> return true;
>>
>> - if (fence->ops->signaled && fence->ops->signaled(fence)) {
>> + rcu_read_lock();
>> + ops = rcu_dereference(fence->ops);
>> + if (ops->signaled && ops->signaled(fence)) {
>
> Maybe you can educate me a bit about RCU here – couldn't this still
> race? If the ops were unloaded before you take rcu_read_lock(),
> rcu_dereference() would give you an invalid pointer here since you
> don't check for !ops, no?
Perfectly correct thinking, yes.
But the check for !ops is added in patch #2 when we actually start to set ops = NULL when the fence signals.
I intentionally separated that because it is basically the second step in making the solution to detach the fence ops from the module by RCU work.
We could merge the two patches together, but I think the separation actually makes sense should anybody start to complain about the additional RCU overhead.
Thanks,
Christian.
>
>
>> + rcu_read_unlock();
>> dma_fence_signal_locked(fence);
>> return true;
>> }
>> + rcu_read_unlock();
>>
>> return false;
>> }
>> @@ -484,13 +501,19 @@ dma_fence_is_signaled_locked(struct dma_fence *fence)
>> static inline bool
>> dma_fence_is_signaled(struct dma_fence *fence)
>> {
>> + const struct dma_fence_ops *ops;
>> +
>> if (dma_fence_test_signaled_flag(fence))
>> return true;
>>
>> - if (fence->ops->signaled && fence->ops->signaled(fence)) {
>> + rcu_read_lock();
>> + ops = rcu_dereference(fence->ops);
>> + if (ops->signaled && ops->signaled(fence)) {
>
> same
>
>
> Danke,
> P.
>
>> + rcu_read_unlock();
>> dma_fence_signal(fence);
>> return true;
>> }
>> + rcu_read_unlock();
>>
>> return false;
>> }
>
On 2/11/26 10:50, Philipp Stanner wrote:
> On Tue, 2026-02-10 at 11:01 +0100, Christian König wrote:
...
>> Using a per-fence spinlock allows completely decoupling spinlock producer
>> and consumer life times, simplifying the handling in most use cases.
>
> That's a good commit message btw, detailing what the motivation is.
> Would be great to see messages like that more frequently :]
Yeah, but they are not so easy to write.
>> trace_dma_fence_init(fence);
>> @@ -1091,7 +1094,7 @@ __dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
>> * dma_fence_init - Initialize a custom fence.
>> * @fence: the fence to initialize
>> * @ops: the dma_fence_ops for operations on this fence
>> - * @lock: the irqsafe spinlock to use for locking this fence
>> + * @lock: optional irqsafe spinlock to use for locking this fence
>> * @context: the execution context this fence is run on
>> * @seqno: a linear increasing sequence number for this context
>> *
>> @@ -1101,6 +1104,10 @@ __dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
>> *
>> * context and seqno are used for easy comparison between fences, allowing
>> * to check which fence is later by simply using dma_fence_later().
>> + *
>> + * It is strongly discouraged to provide an external lock. This is only allowed
>
> "strongly discouraged […] because this does not decouple lock and fence
> life times." ?
Good point, added some more text.
>> + * for legacy use cases when multiple fences need to be prevented from
>> + * signaling out of order.
>
> I think our previous discussions revealed that the external lock does
> not even help with that, does it?
Well only when you provide a ->signaled() callback in the dma_fence_ops.
The reason we have so much different approaches in the dma_fence handling is because it is basically the unification multiple different driver implementations which all targeted more or less different use cases.
>> + * for legacy use cases when multiple fences need to be prevented from
>> + * signaling out of order.
>> */
>> void
>> dma_fence_init64(struct dma_fence *fence, const struct dma_fence_ops *ops,
>> diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
>> index 02af347293d0..c49324505b20 100644
>> --- a/drivers/dma-buf/sync_debug.h
>> +++ b/drivers/dma-buf/sync_debug.h
>> @@ -47,7 +47,7 @@ struct sync_timeline {
>>
>> static inline struct sync_timeline *dma_fence_parent(struct dma_fence *fence)
>> {
>> - return container_of(fence->lock, struct sync_timeline, lock);
>> + return container_of(fence->extern_lock, struct sync_timeline, lock);
>
> You're sure that this will never have to check for the flag?
Yes, the code would have crashed before if anything than a sync_pt created by sync_pt_create was encountered here.
We could drop the wrapper, move the cast to the only place where it matters and document the why and what with a code comment.... but this is all dead code which breaks some of the fundamental dma-fence rules and it is only left here because we can't break the UAPI.
>> static const char *xe_hw_fence_get_driver_name(struct dma_fence *dma_fence)
>> diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
>> index 88c842fc35d5..6eabbb1c471c 100644
>> --- a/include/linux/dma-fence.h
>> +++ b/include/linux/dma-fence.h
>> @@ -34,7 +34,8 @@ struct seq_file;
>> * @ops: dma_fence_ops associated with this fence
>> * @rcu: used for releasing fence with kfree_rcu
>> * @cb_list: list of all callbacks to call
>> - * @lock: spin_lock_irqsave used for locking
>> + * @extern_lock: external spin_lock_irqsave used for locking
>
> Add a "(deprecated)" ?
Done.
>
>> + * @inline_lock: alternative internal spin_lock_irqsave used for locking
>> * @context: execution context this fence belongs to, returned by
>> * dma_fence_context_alloc()
>> * @seqno: the sequence number of this fence inside the execution context,
>> @@ -49,6 +50,7 @@ struct seq_file;
>> * of the time.
>> *
>> * DMA_FENCE_FLAG_INITIALIZED_BIT - fence was initialized
>> + * DMA_FENCE_FLAG_INLINE_LOCK_BIT - use inline spinlock instead of external one
>> * DMA_FENCE_FLAG_SIGNALED_BIT - fence is already signaled
>> * DMA_FENCE_FLAG_TIMESTAMP_BIT - timestamp recorded for fence signaling
>> * DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT - enable_signaling might have been called
>> @@ -66,7 +68,10 @@ struct seq_file;
>> * been completed, or never called at all.
>> */
>> struct dma_fence {
>> - spinlock_t *lock;
>> + union {
>> + spinlock_t *extern_lock;
>> + spinlock_t inline_lock;
>> + };
>> const struct dma_fence_ops __rcu *ops;
>> /*
>> * We clear the callback list on kref_put so that by the time we
>> @@ -100,6 +105,7 @@ struct dma_fence {
>>
>> enum dma_fence_flag_bits {
>> DMA_FENCE_FLAG_INITIALIZED_BIT,
>> + DMA_FENCE_FLAG_INLINE_LOCK_BIT,
>
> Just asking about a nit: what's the order here, always alphabetically?
In which the flags are used in the code flow.
>> DMA_FENCE_FLAG_SEQNO64_BIT,
>> DMA_FENCE_FLAG_SIGNALED_BIT,
>> DMA_FENCE_FLAG_TIMESTAMP_BIT,
>> @@ -381,11 +387,12 @@ dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep)
>> * dma_fence_spinlock - return pointer to the spinlock protecting the fence
>> * @fence: the fence to get the lock from
>> *
>> - * Return the pointer to the extern lock.
>> + * Return either the pointer to the embedded or the external spin lock.
>> */
>> static inline spinlock_t *dma_fence_spinlock(struct dma_fence *fence)
>> {
>> - return fence->lock;
>> + return test_bit(DMA_FENCE_FLAG_INLINE_LOCK_BIT, &fence->flags) ?
>> + &fence->inline_lock : fence->extern_lock;
>
> I personally am not a fan of using '?' for anything longer than 1 line
> and think that
>
> if (condition)
> return a;
>
> return b;
>
> is much better readable.
Mhm, I disagree in this particular case. Especially that you have both possibilities side by side makes it more readable I think.
Regards,
Christian.