drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c- Extension
.c- Size
- 5865 bytes
- Lines
- 250
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
gem/i915_gem_internal.hgem/i915_gem_object.hi915_drv.hi915_list_util.hintel_engine_pm.hintel_gt_buffer_pool.h
Detected Declarations
function bucket_for_sizefunction node_freefunction pool_free_older_thanfunction list_for_each_prevfunction pool_free_workfunction pool_retirefunction intel_gt_buffer_pool_mark_usedfunction node_createfunction intel_gt_get_buffer_poolfunction intel_gt_init_buffer_poolfunction intel_gt_flush_buffer_poolfunction intel_gt_fini_buffer_pool
Annotated Snippet
if (spin_trylock_irq(&pool->lock)) {
struct list_head *pos;
/* Most recent at head; oldest at tail */
list_for_each_prev(pos, list) {
unsigned long age;
node = list_entry(pos, typeof(*node), link);
age = READ_ONCE(node->age);
if (!age || jiffies - age < keep)
break;
/* Check we are the first to claim this node */
if (!xchg(&node->age, 0))
break;
node->free = stale;
stale = node;
}
if (!list_is_last(pos, list))
__list_del_many(pos, list);
spin_unlock_irq(&pool->lock);
}
active |= !list_empty(list);
}
while ((node = stale)) {
stale = stale->free;
node_free(node);
}
return active;
}
static void pool_free_work(struct work_struct *wrk)
{
struct intel_gt_buffer_pool *pool =
container_of(wrk, typeof(*pool), work.work);
struct intel_gt *gt = container_of(pool, struct intel_gt, buffer_pool);
if (pool_free_older_than(pool, HZ))
queue_delayed_work(gt->i915->unordered_wq, &pool->work,
round_jiffies_up_relative(HZ));
}
static void pool_retire(struct i915_active *ref)
{
struct intel_gt_buffer_pool_node *node =
container_of(ref, typeof(*node), active);
struct intel_gt_buffer_pool *pool = node->pool;
struct intel_gt *gt = container_of(pool, struct intel_gt, buffer_pool);
struct list_head *list = bucket_for_size(pool, node->obj->base.size);
unsigned long flags;
if (node->pinned) {
i915_gem_object_unpin_pages(node->obj);
/* Return this object to the shrinker pool */
i915_gem_object_make_purgeable(node->obj);
node->pinned = false;
}
GEM_BUG_ON(node->age);
spin_lock_irqsave(&pool->lock, flags);
list_add_rcu(&node->link, list);
WRITE_ONCE(node->age, jiffies ?: 1); /* 0 reserved for active nodes */
spin_unlock_irqrestore(&pool->lock, flags);
queue_delayed_work(gt->i915->unordered_wq, &pool->work,
round_jiffies_up_relative(HZ));
}
void intel_gt_buffer_pool_mark_used(struct intel_gt_buffer_pool_node *node)
{
assert_object_held(node->obj);
if (node->pinned)
return;
__i915_gem_object_pin_pages(node->obj);
/* Hide this pinned object from the shrinker until retired */
i915_gem_object_make_unshrinkable(node->obj);
node->pinned = true;
}
static struct intel_gt_buffer_pool_node *
node_create(struct intel_gt_buffer_pool *pool, size_t sz,
Annotation
- Immediate include surface: `gem/i915_gem_internal.h`, `gem/i915_gem_object.h`, `i915_drv.h`, `i915_list_util.h`, `intel_engine_pm.h`, `intel_gt_buffer_pool.h`.
- Detected declarations: `function bucket_for_size`, `function node_free`, `function pool_free_older_than`, `function list_for_each_prev`, `function pool_free_work`, `function pool_retire`, `function intel_gt_buffer_pool_mark_used`, `function node_create`, `function intel_gt_get_buffer_pool`, `function intel_gt_init_buffer_pool`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.