Skip to content

Commit

Permalink
drm/i915: Allocate intel_engine_cs structure only for the enabled eng…
Browse files Browse the repository at this point in the history
…ines

With the possibility of addition of many more number of rings in future,
the drm_i915_private structure could bloat as an array, of type
intel_engine_cs, is embedded inside it.
	struct intel_engine_cs engine[I915_NUM_ENGINES];
Though this is still fine as generally there is only a single instance of
drm_i915_private structure used, but not all of the possible rings would be
enabled or active on most of the platforms. Some memory can be saved by
allocating intel_engine_cs structure only for the enabled/active engines.
Currently the engine/ring ID is kept static and dev_priv->engine[] is simply
indexed using the enums defined in intel_engine_id.
To save memory and continue using the static engine/ring IDs, 'engine' is
defined as an array of pointers.
	struct intel_engine_cs *engine[I915_NUM_ENGINES];
dev_priv->engine[engine_ID] will be NULL for disabled engine instances.

There is a text size reduction of 928 bytes, from 1028200 to 1027272, for
i915.o file (but for i915.ko file text size remain same as 1193131 bytes).

v2:
- Remove the engine iterator field added in drm_i915_private structure,
  instead pass a local iterator variable to the for_each_engine**
  macros. (Chris)
- Do away with intel_engine_initialized() and instead directly use the
  NULL pointer check on engine pointer. (Chris)

v3:
- Remove for_each_engine_id() macro, as the updated macro for_each_engine()
  can be used in place of it. (Chris)
- Protect the access to Render engine Fault register with a NULL check, as
  engine specific init is done later in Driver load sequence.

v4:
- Use !!dev_priv->engine[VCS] style for the engine check in getparam. (Chris)
- Kill the superfluous init_engine_lists().

v5:
- Cleanup the intel_engines_init() & intel_engines_setup(), with respect to
  allocation of intel_engine_cs structure. (Chris)

v6:
- Rebase.

v7:
- Optimize the for_each_engine_masked() macro. (Chris)
- Change the type of 'iter' local variable to enum intel_engine_id. (Chris)
- Rebase.

v8: Rebase.

v9: Rebase.

v10:
- For index calculation use engine ID instead of pointer based arithmetic in
  intel_engine_sync_index() as engine pointers are not contiguous now (Chris)
- For appropriateness, rename local enum variable 'iter' to 'id'. (Joonas)
- Use for_each_engine macro for cleanup in intel_engines_init() and remove
  check for NULL engine pointer in cleanup() routines. (Joonas)

v11: Rebase.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Akash Goel <akash.goel@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1476378888-7372-1-git-send-email-akash.goel@intel.com
  • Loading branch information
Akash Goel authored and Tvrtko Ursulin committed Oct 14, 2016
1 parent 86e83e3 commit 3b3f165
Show file tree
Hide file tree
Showing 22 changed files with 194 additions and 158 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/i915_cmd_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1308,10 +1308,11 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;
bool active = false;

/* If the command parser is not enabled, report 0 - unsupported */
for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
if (intel_engine_needs_cmd_parser(engine)) {
active = true;
break;
Expand Down
59 changes: 35 additions & 24 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
obj->base.size / 1024,
obj->base.read_domains,
obj->base.write_domain);
for_each_engine_id(engine, dev_priv, id)
for_each_engine(engine, dev_priv, id)
seq_printf(m, "%x ",
i915_gem_active_get_seqno(&obj->last_read[id],
&obj->base.dev->struct_mutex));
Expand Down Expand Up @@ -323,11 +323,12 @@ static void print_batch_pool_stats(struct seq_file *m,
struct drm_i915_gem_object *obj;
struct file_stats stats;
struct intel_engine_cs *engine;
enum intel_engine_id id;
int j;

memset(&stats, 0, sizeof(stats));

for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
list_for_each_entry(obj,
&engine->batch_pool.cache_list[j],
Expand Down Expand Up @@ -596,14 +597,15 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data)
struct drm_device *dev = &dev_priv->drm;
struct drm_i915_gem_object *obj;
struct intel_engine_cs *engine;
enum intel_engine_id id;
int total = 0;
int ret, j;

ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;

for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) {
int count;

Expand Down Expand Up @@ -655,16 +657,17 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct drm_device *dev = &dev_priv->drm;
struct intel_engine_cs *engine;
struct drm_i915_gem_request *req;
struct intel_engine_cs *engine;
enum intel_engine_id id;
int ret, any;

ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;

any = 0;
for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
int count;

count = 0;
Expand Down Expand Up @@ -710,8 +713,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct intel_engine_cs *engine;
enum intel_engine_id id;

for_each_engine(engine, dev_priv)
for_each_engine(engine, dev_priv, id)
i915_ring_seqno_info(m, engine);

return 0;
Expand All @@ -722,6 +726,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct intel_engine_cs *engine;
enum intel_engine_id id;
int i, pipe;

intel_runtime_pm_get(dev_priv);
Expand Down Expand Up @@ -890,7 +895,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
seq_printf(m, "Graphics Interrupt mask: %08x\n",
I915_READ(GTIMR));
}
for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
if (INTEL_GEN(dev_priv) >= 6) {
seq_printf(m,
"Graphics Interrupt mask (%s): %08x\n",
Expand Down Expand Up @@ -938,7 +943,7 @@ static int i915_hws_info(struct seq_file *m, void *data)
const u32 *hws;
int i;

engine = &dev_priv->engine[(uintptr_t)node->info_ent->data];
engine = dev_priv->engine[(uintptr_t)node->info_ent->data];
hws = engine->status_page.page_addr;
if (hws == NULL)
return 0;
Expand Down Expand Up @@ -1329,12 +1334,12 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)

intel_runtime_pm_get(dev_priv);

for_each_engine_id(engine, dev_priv, id) {
for_each_engine(engine, dev_priv, id) {
acthd[id] = intel_engine_get_active_head(engine);
seqno[id] = intel_engine_get_seqno(engine);
}

intel_engine_get_instdone(&dev_priv->engine[RCS], &instdone);
intel_engine_get_instdone(dev_priv->engine[RCS], &instdone);

intel_runtime_pm_put(dev_priv);

Expand All @@ -1345,7 +1350,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
} else
seq_printf(m, "Hangcheck inactive\n");

for_each_engine_id(engine, dev_priv, id) {
for_each_engine(engine, dev_priv, id) {
struct intel_breadcrumbs *b = &engine->breadcrumbs;
struct rb_node *rb;

Expand Down Expand Up @@ -1944,6 +1949,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
struct drm_device *dev = &dev_priv->drm;
struct intel_engine_cs *engine;
struct i915_gem_context *ctx;
enum intel_engine_id id;
int ret;

ret = mutex_lock_interruptible(&dev->struct_mutex);
Expand All @@ -1970,7 +1976,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
seq_putc(m, ctx->remap_slice ? 'R' : 'r');
seq_putc(m, '\n');

for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
struct intel_context *ce = &ctx->engine[engine->id];

seq_printf(m, "%s: ", engine->name);
Expand Down Expand Up @@ -2037,6 +2043,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
struct drm_device *dev = &dev_priv->drm;
struct intel_engine_cs *engine;
struct i915_gem_context *ctx;
enum intel_engine_id id;
int ret;

if (!i915.enable_execlists) {
Expand All @@ -2049,7 +2056,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
return ret;

list_for_each_entry(ctx, &dev_priv->context_list, link)
for_each_engine(engine, dev_priv)
for_each_engine(engine, dev_priv, id)
i915_dump_lrc_obj(m, ctx, engine);

mutex_unlock(&dev->struct_mutex);
Expand Down Expand Up @@ -2158,14 +2165,15 @@ static int per_file_ctx(int id, void *ptr, void *data)
static void gen8_ppgtt_info(struct seq_file *m,
struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
struct intel_engine_cs *engine;
enum intel_engine_id id;
int i;

if (!ppgtt)
return;

for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
seq_printf(m, "%s\n", engine->name);
for (i = 0; i < 4; i++) {
u64 pdp = I915_READ(GEN8_RING_PDP_UDW(engine, i));
Expand All @@ -2180,11 +2188,12 @@ static void gen6_ppgtt_info(struct seq_file *m,
struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;

if (IS_GEN6(dev_priv))
seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));

for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
seq_printf(m, "%s\n", engine->name);
if (IS_GEN7(dev_priv))
seq_printf(m, "GFX_MODE: 0x%08x\n",
Expand Down Expand Up @@ -2253,9 +2262,10 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
static int count_irq_waiters(struct drm_i915_private *i915)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;
int count = 0;

for_each_engine(engine, i915)
for_each_engine(engine, i915, id)
count += intel_engine_has_waiter(engine);

return count;
Expand Down Expand Up @@ -2418,7 +2428,7 @@ static void i915_guc_client_info(struct seq_file *m,
seq_printf(m, "\tFailed doorbell: %u\n", client->b_fail);
seq_printf(m, "\tLast submission result: %d\n", client->retcode);

for_each_engine_id(engine, dev_priv, id) {
for_each_engine(engine, dev_priv, id) {
u64 submissions = client->submissions[id];
tot += submissions;
seq_printf(m, "\tSubmissions: %llu %s\n",
Expand Down Expand Up @@ -2461,7 +2471,7 @@ static int i915_guc_info(struct seq_file *m, void *data)
seq_printf(m, "GuC last action error code: %d\n", guc.action_err);

seq_printf(m, "\nGuC submissions:\n");
for_each_engine_id(engine, dev_priv, id) {
for_each_engine(engine, dev_priv, id) {
u64 submissions = guc.submissions[id];
total += submissions;
seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n",
Expand Down Expand Up @@ -3082,8 +3092,9 @@ static int i915_engine_info(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct intel_engine_cs *engine;
enum intel_engine_id id;

for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
struct intel_breadcrumbs *b = &engine->breadcrumbs;
struct drm_i915_gem_request *rq;
struct rb_node *rb;
Expand Down Expand Up @@ -3231,7 +3242,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
page = i915_gem_object_get_page(dev_priv->semaphore->obj, 0);

seqno = (uint64_t *)kmap_atomic(page);
for_each_engine_id(engine, dev_priv, id) {
for_each_engine(engine, dev_priv, id) {
uint64_t offset;

seq_printf(m, "%s\n", engine->name);
Expand All @@ -3256,15 +3267,15 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
kunmap_atomic(seqno);
} else {
seq_puts(m, " Last signal:");
for_each_engine(engine, dev_priv)
for_each_engine(engine, dev_priv, id)
for (j = 0; j < num_rings; j++)
seq_printf(m, "0x%08x\n",
I915_READ(engine->semaphore.mbox.signal[j]));
seq_putc(m, '\n');
}

seq_puts(m, "\nSync seqno:\n");
for_each_engine(engine, dev_priv) {
for_each_engine(engine, dev_priv, id) {
for (j = 0; j < num_rings; j++)
seq_printf(m, " 0x%08x ",
engine->semaphore.sync_seqno[j]);
Expand Down Expand Up @@ -3320,7 +3331,7 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
intel_runtime_pm_get(dev_priv);

seq_printf(m, "Workarounds applied: %d\n", workarounds->count);
for_each_engine_id(engine, dev_priv, id)
for_each_engine(engine, dev_priv, id)
seq_printf(m, "HW whitelist count for %s: %d\n",
engine->name, workarounds->hw_whitelist_count[id]);
for (i = 0; i < workarounds->count; ++i) {
Expand Down
11 changes: 6 additions & 5 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,16 @@ static int i915_getparam(struct drm_device *dev, void *data,
value = dev_priv->overlay ? 1 : 0;
break;
case I915_PARAM_HAS_BSD:
value = intel_engine_initialized(&dev_priv->engine[VCS]);
value = !!dev_priv->engine[VCS];
break;
case I915_PARAM_HAS_BLT:
value = intel_engine_initialized(&dev_priv->engine[BCS]);
value = !!dev_priv->engine[BCS];
break;
case I915_PARAM_HAS_VEBOX:
value = intel_engine_initialized(&dev_priv->engine[VECS]);
value = !!dev_priv->engine[VECS];
break;
case I915_PARAM_HAS_BSD2:
value = intel_engine_initialized(&dev_priv->engine[VCS2]);
value = !!dev_priv->engine[VCS2];
break;
case I915_PARAM_HAS_EXEC_CONSTANTS:
value = INTEL_GEN(dev_priv) >= 4;
Expand Down Expand Up @@ -1707,10 +1707,11 @@ int i915_resume_switcheroo(struct drm_device *dev)
static void disable_engines_irq(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;

/* Ensure irq handler finishes, and not run again. */
disable_irq(dev_priv->drm.irq);
for_each_engine(engine, dev_priv)
for_each_engine(engine, dev_priv, id)
tasklet_kill(&engine->irq_tasklet);
}

Expand Down
22 changes: 7 additions & 15 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1808,7 +1808,7 @@ struct drm_i915_private {

struct pci_dev *bridge_dev;
struct i915_gem_context *kernel_context;
struct intel_engine_cs engine[I915_NUM_ENGINES];
struct intel_engine_cs *engine[I915_NUM_ENGINES];
struct i915_vma *semaphore;
u32 next_seqno;

Expand Down Expand Up @@ -2125,19 +2125,11 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
}

/* Simple iterator over all initialised engines */
#define for_each_engine(engine__, dev_priv__) \
for ((engine__) = &(dev_priv__)->engine[0]; \
(engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
(engine__)++) \
for_each_if (intel_engine_initialized(engine__))

/* Iterator with engine_id */
#define for_each_engine_id(engine__, dev_priv__, id__) \
for ((engine__) = &(dev_priv__)->engine[0], (id__) = 0; \
(engine__) < &(dev_priv__)->engine[I915_NUM_ENGINES]; \
(engine__)++) \
for_each_if (((id__) = (engine__)->id, \
intel_engine_initialized(engine__)))
#define for_each_engine(engine__, dev_priv__, id__) \
for ((id__) = 0; \
(id__) < I915_NUM_ENGINES; \
(id__)++) \
for_each_if ((engine__) = (dev_priv__)->engine[(id__)])

#define __mask_next_bit(mask) ({ \
int __idx = ffs(mask) - 1; \
Expand All @@ -2148,7 +2140,7 @@ static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
/* Iterator over subset of engines selected by mask */
#define for_each_engine_masked(engine__, dev_priv__, mask__, tmp__) \
for (tmp__ = mask__ & INTEL_INFO(dev_priv__)->ring_mask; \
tmp__ ? (engine__ = &(dev_priv__)->engine[__mask_next_bit(tmp__)]), 1 : 0; )
tmp__ ? (engine__ = (dev_priv__)->engine[__mask_next_bit(tmp__)]), 1 : 0; )

enum hdmi_force_audio {
HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */
Expand Down
Loading

0 comments on commit 3b3f165

Please sign in to comment.