All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: Deepak Goyal <dgoyal-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
	bskeggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH] pmu/gk20a: PMU boot support.
Date: Fri, 13 Mar 2015 19:12:01 +0900	[thread overview]
Message-ID: <5502B7F1.7030700@nvidia.com> (raw)
In-Reply-To: <1426055631-1166-1-git-send-email-dgoyal-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Due to the length of the patch there are many things to fix. This review 
alone won't cover all of them, but is mainly an attempt to reduce the 
amount of code and to split this.

On Wed, Mar 11, 2015 at 3:33 PM, Deepak Goyal <dgoyal@nvidia.com> wrote:
 > It adds PMU boot support.It loads PMU
 > firmware into PMU falcon.RM/Kernel driver
 > receives INIT ack (through interrupt mechanism)
 > from PMU when PMU boots with success.

This commit log is strangely formatted. You want to break lines of git 
commit lots around column 70, not 50. Also don't forget the space after 
the end of your sentences.

The log itself also lacks informative value, especially considering the 
length of this patch. Please assume your reader is completely unfamiliar 
with your work, and explain in detail what your patch does, even the 
parts that seem obvious. Some questions that come to mind when reading 
the log:

- What is the PMU firmware do?
- What is RM? (this is not the terminology used by Nouveau, so better to 
avoid using it altogether)
- What value does this patch add to the project?

I understand that this patch clears the way for follow-up patches that 
will actually add features. Please state this clearly in the log, and 
explain what these features are. No code can be merged upstream until 
its benefits are clearly understood.

Review follows, I have changed the order of files to comment on the 
structures before the code.

 > diff --git a/drm/nouveau/nvkm/subdev/pmu/priv.h 
b/drm/nouveau/nvkm/subdev/pmu/priv.h
 > index 998410563bfd..c4686e418582 100644
 > --- a/drm/nouveau/nvkm/subdev/pmu/priv.h
 > +++ b/drm/nouveau/nvkm/subdev/pmu/priv.h
 > @@ -2,7 +2,91 @@
 >  #define __NVKM_PMU_PRIV_H__
 >  #include <subdev/pmu.h>
 >  #include <subdev/pmu/fuc/os.h>
 > +#include <core/object.h>
 > +#include <core/device.h>
 > +#include <core/parent.h>
 > +#include <core/mm.h>
 > +#include <linux/rwsem.h>
 > +#include <linux/slab.h>
 > +#include <subdev/mmu.h>
 > +#include <core/gpuobj.h>
 >
 > +static inline u32 u64_hi32(u64 n)
 > +{
 > +       return (u32)((n >> 32) & ~(u32)0);
 > +}
 > +
 > +static inline u32 u64_lo32(u64 n)
 > +{
 > +       return (u32)(n & ~(u32)0);
 > +}

Use the lower_32_bits() and upper_32_bits() macros instead.

 > +
 > +/* #define ALLOCATOR_DEBUG */

This line is useless...

 > +
 > +/* main struct */

... and this comment uninformative.

 > +struct nvkm_pmu_allocator {
 > +
 > +       char name[32];                  /* name for allocator */
 > +/*struct rb_root rb_root;*/            /* rb tree root for blocks */

Do not comment out members that we don't need. If it's unneeded, just 
remove it.

 > +
 > +       u32 base;                       /* min value of this linear 
space */
 > +       u32 limit;                      /* max value = limit - 1 */
 > +
 > +       unsigned long *bitmap;          /* bitmap */
 > +
 > +       struct gk20a_alloc_block *block_first;  /* first block in list */
 > +       struct gk20a_alloc_block *block_recent; /* last visited block */
 > +
 > +       u32 first_free_addr;            /* first free addr, non-contigous
 > +                                          allocation preferred start,
 > +                                          in order to pick up small 
holes */
 > +       u32 last_free_addr;             /* last free addr, contiguous
 > +                                          allocation preferred start */
 > +       u32 cached_hole_size;           /* max free hole size up to
 > +                                          last_free_addr */
 > +       u32 block_count;                /* number of blocks */
 > +
 > +       struct rw_semaphore rw_sema;    /* lock */
 > +       struct kmem_cache *block_cache; /* slab cache */
 > +
 > +       /* if enabled, constrain to [base, limit) */
 > +       struct {
 > +               bool enable;
 > +               u32 base;
 > +               u32 limit;
 > +       } constraint;
 > +
 > +       int (*alloc)(struct nvkm_pmu_allocator *allocator,
 > +               u32 *addr, u32 len, u32 align);
 > +       int (*free)(struct nvkm_pmu_allocator *allocator,
 > +               u32 addr, u32 len, u32 align);
 > +
 > +};
 > +
 > +int nvkm_pmu_allocator_init(struct nvkm_pmu_allocator *allocator,
 > +                       const char *name, u32 base, u32 size);
 > +void nvkm_pmu_allocator_destroy(struct nvkm_pmu_allocator *allocator);
 > +
 > +int nvkm_pmu_allocator_block_alloc(struct nvkm_pmu_allocator *allocator,
 > +                       u32 *addr, u32 len, u32 align);
 > +
 > +int nvkm_pmu_allocator_block_free(struct nvkm_pmu_allocator *allocator,
 > +                       u32 addr, u32 len, u32 align);

So from the nvkm_pmu_allocator struct and these function prototypes, 
this looks like a pretty casual address space allocator. Nouveau already 
has such an allocator: nvkm_mm. Check it out, it will do all that you 
need and you can remove a lot of code from this patch.

 > +
 > +#if defined(ALLOCATOR_DEBUG)
 > +
 > +#define allocator_dbg(alloctor, format, arg...) 
            \
 > +do {                                                           \
 > +       if (1)                                                  \
 > +               pr_debug("nvkm_pmu_allocator (%s) %s: " format "\n",\
 > +                       alloctor->name, __func__, ##arg);\
 > +} while (0)
 > +
 > +#else /* ALLOCATOR_DEBUG */
 > +
 > +#define allocator_dbg(format, arg...)

I'd prefer if you use the nv_debug() macro in place of this one, but it 
will go away with the allocator anyway...

 > +
 > +#endif /* ALLOCATOR_DEBUG */
 >  #define nvkm_pmu_create(p, e, o, d) 
         \
 >         nvkm_pmu_create_((p), (e), (o), sizeof(**d), (void **)d)
 >  #define nvkm_pmu_destroy(p) 
         \
 > @@ -26,6 +110,179 @@ int _nvkm_pmu_ctor(struct nvkm_object *, struct 
nvkm_object *,
 >  int _nvkm_pmu_init(struct nvkm_object *);
 >  int _nvkm_pmu_fini(struct nvkm_object *, bool);
 >  void nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable);
 > +#define PMU_PG_IDLE_THRESHOLD                  15000
 > +#define PMU_PG_POST_POWERUP_IDLE_THRESHOLD     1000000

I do not see these macros being used anywhere in your code.

 > +
 > +/* state transition :
 > +    OFF => [OFF_ON_PENDING optional] => ON_PENDING => ON => OFF
 > +    ON => OFF is always synchronized */
 > +#define PMU_ELPG_STAT_OFF              0   /* elpg is off */
 > +#define PMU_ELPG_STAT_ON               1   /* elpg is on */
 > +/* elpg is off, ALLOW cmd has been sent, wait for ack */
 > +#define PMU_ELPG_STAT_ON_PENDING       2
 > +/* elpg is on, DISALLOW cmd has been sent, wait for ack */
 > +#define PMU_ELPG_STAT_OFF_PENDING      3
 > +/* elpg is off, caller has requested on, but ALLOW
 > +cmd hasn't been sent due to ENABLE_ALLOW delay */
 > +#define PMU_ELPG_STAT_OFF_ON_PENDING   4

Same here. If they are used by a future patch, introduce them at the 
time they actually become useful.

 > +
 > +/* Falcon Register index */
 > +#define PMU_FALCON_REG_R0              (0)
 > +#define PMU_FALCON_REG_R1              (1)
 > +#define PMU_FALCON_REG_R2              (2)
 > +#define PMU_FALCON_REG_R3              (3)
 > +#define PMU_FALCON_REG_R4              (4)
 > +#define PMU_FALCON_REG_R5              (5)
 > +#define PMU_FALCON_REG_R6              (6)
 > +#define PMU_FALCON_REG_R7              (7)
 > +#define PMU_FALCON_REG_R8              (8)
 > +#define PMU_FALCON_REG_R9              (9)
 > +#define PMU_FALCON_REG_R10             (10)
 > +#define PMU_FALCON_REG_R11             (11)
 > +#define PMU_FALCON_REG_R12             (12)
 > +#define PMU_FALCON_REG_R13             (13)
 > +#define PMU_FALCON_REG_R14             (14)
 > +#define PMU_FALCON_REG_R15             (15)
 > +#define PMU_FALCON_REG_IV0             (16)
 > +#define PMU_FALCON_REG_IV1             (17)
 > +#define PMU_FALCON_REG_UNDEFINED       (18)
 > +#define PMU_FALCON_REG_EV              (19)
 > +#define PMU_FALCON_REG_SP              (20)
 > +#define PMU_FALCON_REG_PC              (21)
 > +#define PMU_FALCON_REG_IMB             (22)
 > +#define PMU_FALCON_REG_DMB             (23)
 > +#define PMU_FALCON_REG_CSW             (24)
 > +#define PMU_FALCON_REG_CCR             (25)
 > +#define PMU_FALCON_REG_SEC             (26)
 > +#define PMU_FALCON_REG_CTX             (27)
 > +#define PMU_FALCON_REG_EXCI            (28)
 > +#define PMU_FALCON_REG_RSVD0           (29)
 > +#define PMU_FALCON_REG_RSVD1           (30)
 > +#define PMU_FALCON_REG_RSVD2           (31)
 > +#define PMU_FALCON_REG_SIZE            (32)

These ones are ok since it would not make sense to define only part of 
the regs...

 > +
 > +/* Choices for pmu_state */
 > +#define PMU_STATE_OFF                  0 /* PMU is off */
 > +#define PMU_STATE_STARTING             1 /* PMU is on, but not booted */
 > +#define PMU_STATE_INIT_RECEIVED                2 /* PMU init message 
received */
 > +#define PMU_STATE_ELPG_BOOTING         3 /* PMU is booting */
 > +#define PMU_STATE_ELPG_BOOTED          4 /* ELPG is initialized */
 > +#define PMU_STATE_LOADING_PG_BUF       5 /* Loading PG buf */
 > +#define PMU_STATE_LOADING_ZBC          6 /* Loading ZBC buf */
 > +#define PMU_STATE_STARTED              7 /* Fully unitialized */

But here again, the last 5 states are not used yet, so please introduce 
them as they become needed.

 > +
 > +#define PMU_QUEUE_COUNT                5
 > +
 > +#define PMU_MAX_NUM_SEQUENCES          (256)
 > +#define PMU_SEQ_BIT_SHIFT              (5)
 > +#define PMU_SEQ_TBL_SIZE       \
 > +               (PMU_MAX_NUM_SEQUENCES >> PMU_SEQ_BIT_SHIFT)
 > +
 > +#define PMU_SHA1_GID_SIGNATURE         0xA7C66AD2
 > +#define PMU_SHA1_GID_SIGNATURE_SIZE    4
 > +
 > +#define PMU_SHA1_GID_SIZE      16
 > +
 > +struct pmu_queue {
 > +

Empty blank line.

 > +       /* used by hw, for BIOS/SMI queue */
 > +       u32 mutex_id;
 > +       u32 mutex_lock;
 > +       /* used by sw, for LPQ/HPQ queue */
 > +       struct mutex mutex;
 > +
 > +       /* current write position */
 > +       u32 position;
 > +       /* physical dmem offset where this queue begins */
 > +       u32 offset;
 > +       /* logical queue identifier */
 > +       u32 id;
 > +       /* physical queue index */
 > +       u32 index;
 > +       /* in bytes */
 > +       u32 size;
 > +
 > +       /* open-flag */
 > +       u32 oflag;
 > +       bool opened; /* opened implies locked */
 > +};
 > +
 > +struct pmu_sha1_gid {
 > +       bool valid;
 > +       u8 gid[PMU_SHA1_GID_SIZE];
 > +};
 > +
 > +struct pmu_sha1_gid_data {
 > +       u8 signature[PMU_SHA1_GID_SIGNATURE_SIZE];
 > +       u8 gid[PMU_SHA1_GID_SIZE];
 > +};
 > +
 > +struct pmu_desc {
 > +

Empty blank line.

 > +       struct pmu_ucode_desc *desc;
 > +       struct pmu_buf_desc ucode;
 > +
 > +       struct pmu_buf_desc pg_buf;

This member doesn't seem to be needed now.

 > +       /* TBD: remove this if ZBC seq is fixed */
 > +       struct pmu_buf_desc seq_buf;
 > +       struct pmu_buf_desc trace_buf;
 > +       bool buf_loaded;

buf_loaded is never referenced in this code.

 > +
 > +       struct pmu_sha1_gid gid_info;
 > +
 > +       struct pmu_queue queue[PMU_QUEUE_COUNT];
 > +
 > +       struct pmu_sequence *seq;

Wrong. pmu_sequence is defined in gk20a.h. This file is a generic one. 
Why would PMUs for other GPUs embed GK20A-specific structures?

Actually it seems like the whole pmu_desc should be moved to 
GK20A-specific files, since it is not used elsewhere for now.

 > +       unsigned long pmu_seq_tbl[PMU_SEQ_TBL_SIZE];
 > +       u32 next_seq_desc;
 > +
 > +       struct pmu_mutex *mutex;
 > +       u32 mutex_cnt;
 > +
 > +       struct mutex pmu_copy_lock;
 > +       struct mutex pmu_seq_lock;
 > +
 > +       struct nvkm_pmu_allocator dmem;

So as explained above, this should be replaced by a nvkm_mm.

 > +
 > +       u32 *ucode_image;
 > +       bool pmu_ready;
 > +
 > +       u32 zbc_save_done;

Yet another unreferenced member...

 > +
 > +       u32 stat_dmem_offset;

And another one.

 > +
 > +       u32 elpg_stat;

And another one.

 > +
 > +       int pmu_state;
 > +
 > +#define PMU_ELPG_ENABLE_ALLOW_DELAY_MSEC       1 /* msec */

And another one.

 > +       struct work_struct isr_workq;
 > +       struct mutex elpg_mutex; /* protect elpg enable/disable */

And another one.

 > +/* disable -1, enable +1, <=0 elpg disabled, > 0 elpg enabled */
 > +       int elpg_refcnt;

Here too.

 > +
 > +       bool initialized;
 > +
 > +       void (*remove_support)(struct pmu_desc *pmu);

So this function pointer is set, but never called! Is it unneeded, or 
have you forgot to call it when you should have?

 > +       bool sw_ready;
 > +       bool perfmon_ready;

Unneeded member again.

 > +
 > +       u32 sample_buffer;
 > +       u32 load_shadow;
 > +       u32 load_avg;
 > +
 > +       struct mutex isr_mutex;
 > +       bool isr_enabled;
 > +
 > +       bool zbc_ready;

This is only set to false in the destroy() function, so I guess you 
don't need this now...

 > +       unsigned long perfmon_events_cnt;
 > +       bool perfmon_sampling_enabled;
 > +       u8 pmu_mode;
 > +       u32 falcon_id;
 > +       u32 aelpg_param[5];

And all these 5 members are also not needed now it seems.

 > +       void *pmu_chip_data;

 From how you are using this member (to store a pointer to a kzalloc'd 
pmu_gk20a_data), it seems to be unneeded. Put the content of 
pmu_gk20a_data into gk20a_pmu_priv, and get rid of both this member and 
pmu_gk20a_data.

And actually since both members of pmu_gk20a_data are completely 
unreferenced, they can be added in a later patch anyway, when they 
actually become useful.

 > +       struct nvkm_pmu *pmu;
 > +};
 >
 >  struct nvkm_pmu_impl {
 >         struct nvkm_oclass base;
 > @@ -39,5 +296,12 @@ struct nvkm_pmu_impl {
 >         } data;
 >
 >         void (*pgob)(struct nvkm_pmu *, bool);
 > +       struct pmu_desc pmudata;
 >  };
 > +
 > +static inline struct nvkm_pmu *impl_from_pmu(struct pmu_desc *pmu)
 > +{
 > +       return pmu->pmu;
 > +}
 > +
 >  #endif
 > diff --git a/drm/nouveau/include/nvkm/subdev/pmu.h 
b/drm/nouveau/include/nvkm/subdev/pmu.h
 > index 7b86acc634a0..659b4e0ba02b 100644
 > --- a/drm/nouveau/include/nvkm/subdev/pmu.h
 > +++ b/drm/nouveau/include/nvkm/subdev/pmu.h
 > @@ -1,7 +1,20 @@
 >  #ifndef __NVKM_PMU_H__
 >  #define __NVKM_PMU_H__
 >  #include <core/subdev.h>
 > +#include <core/device.h>
 > +#include <subdev/mmu.h>
 > +#include <linux/debugfs.h>
 >
 > +struct pmu_buf_desc {
 > +       struct nvkm_gpuobj *pmubufobj;
 > +       struct nvkm_vma pmubufvma;

Your struct is already called "pmu_buf", so maybe call these members 
"obj" and "vma" simply.

 > +       size_t size;
 > +};
 > +struct pmu_priv_vm {
 > +       struct nvkm_gpuobj *mem;
 > +       struct nvkm_gpuobj *pgd;
 > +       struct nvkm_vm *vm;
 > +};
 >  struct nvkm_pmu {
 >         struct nvkm_subdev base;
 >
 > @@ -20,9 +33,20 @@ struct nvkm_pmu {
 >                 u32 message;
 >                 u32 data[2];
 >         } recv;
 > -
 > +       wait_queue_head_t init_wq;

This wq is initialized and never used.

 > +       bool gr_initialised;

Member only written once.

 > +       struct dentry *debugfs;
 > +       struct pmu_buf_desc *pg_buf;

This member is never used, and by transition neither is the pg_buf of 
struct pmu_desc.

 > +       struct pmu_priv_vm *pmuvm;
 >         int  (*message)(struct nvkm_pmu *, u32[2], u32, u32, u32, u32);
 >         void (*pgob)(struct nvkm_pmu *, bool);
 > +       int (*pmu_mutex_acquire)(struct nvkm_pmu *, u32 id, u32 *token);

Never used because you are calling the function you affect to the 
pointer directly in the code (which happens to also be called 
pmu_mutex_acquire!)

 > +       int (*pmu_mutex_release)(struct nvkm_pmu *, u32 id, u32 *token);

Same here.

 > +       int (*pmu_load_norm)(struct nvkm_pmu *pmu, u32 *load);
 > +       int (*pmu_load_update)(struct nvkm_pmu *pmu);
 > +       void (*pmu_reset_load_counters)(struct nvkm_pmu *pmu);
 > +       void (*pmu_get_load_counters)(struct nvkm_pmu *pmu, u32 
*busy_cycles,
 > +               u32 *total_cycles);

These four ones are never called. Introduce members and functions only 
when they become needed.

 >  };
 >
 >  static inline struct nvkm_pmu *
 > diff --git a/drm/nouveau/nvkm/subdev/pmu/base.c 
b/drm/nouveau/nvkm/subdev/pmu/base.c
 > index 054b2d2eec35..6afd389b9764 100644
 > --- a/drm/nouveau/nvkm/subdev/pmu/base.c
 > +++ b/drm/nouveau/nvkm/subdev/pmu/base.c
 > @@ -25,6 +25,114 @@
 >
 >  #include <subdev/timer.h>


 >
 > +/* init allocator struct */
 > +int nvkm_pmu_allocator_init(struct nvkm_pmu_allocator *allocator,
 > +               const char *name, u32 start, u32 len)
 > +{
 > +       memset(allocator, 0, sizeof(struct nvkm_pmu_allocator));
 > +
 > +       strncpy(allocator->name, name, 32);
 > +
 > +       allocator->base = start;
 > +       allocator->limit = start + len - 1;
 > +
 > +       allocator->bitmap = kcalloc(BITS_TO_LONGS(len), sizeof(long),
 > +                       GFP_KERNEL);
 > +       if (!allocator->bitmap)
 > +               return -ENOMEM;
 > +
 > +       allocator_dbg(allocator, "%s : base %d, limit %d",
 > +               allocator->name, allocator->base);
 > +
 > +       init_rwsem(&allocator->rw_sema);
 > +
 > +       allocator->alloc = nvkm_pmu_allocator_block_alloc;
 > +       allocator->free = nvkm_pmu_allocator_block_free;
 > +
 > +       return 0;
 > +}
 > +
 > +/* destroy allocator, free all remaining blocks if any */
 > +void nvkm_pmu_allocator_destroy(struct nvkm_pmu_allocator *allocator)
 > +{
 > +       down_write(&allocator->rw_sema);
 > +
 > +       kfree(allocator->bitmap);
 > +
 > +       memset(allocator, 0, sizeof(struct nvkm_pmu_allocator));
 > +}
 > +
 > +/*
 > + * *addr != ~0 for fixed address allocation. if *addr == 0, base addr is
 > + * returned to caller in *addr.
 > + *
 > + * contiguous allocation, which allocates one block of
 > + * contiguous address.
 > +*/
 > +int nvkm_pmu_allocator_block_alloc(struct nvkm_pmu_allocator *allocator,
 > +               u32 *addr, u32 len, u32 align)
 > +{
 > +       unsigned long _addr;
 > +
 > +       allocator_dbg(allocator, "[in] addr %d, len %d", *addr, len);
 > +
 > +       if ((*addr != 0 && *addr < allocator->base) || /* check addr 
range */
 > +           *addr + len > allocator->limit || /* check addr range */
 > +           *addr & (align - 1) || /* check addr alignment */
 > +            len == 0)                        /* check len */
 > +               return -EINVAL;
 > +
 > +       len = ALIGN(len, align);
 > +       if (!len)
 > +               return -ENOMEM;
 > +
 > +       down_write(&allocator->rw_sema);
 > +
 > +       _addr = bitmap_find_next_zero_area(allocator->bitmap,
 > +                       allocator->limit - allocator->base + 1,
 > +                       *addr ? (*addr - allocator->base) : 0,
 > +                       len,
 > +                       align - 1);
 > +       if ((_addr > allocator->limit - allocator->base + 1) ||
 > +           (*addr && *addr != (_addr + allocator->base))) {
 > +               up_write(&allocator->rw_sema);
 > +               return -ENOMEM;
 > +       }
 > +
 > +       bitmap_set(allocator->bitmap, _addr, len);
 > +       *addr = allocator->base + _addr;
 > +
 > +       up_write(&allocator->rw_sema);
 > +
 > +       allocator_dbg(allocator, "[out] addr %d, len %d", *addr, len);
 > +
 > +       return 0;
 > +}
 > +
 > +/* free all blocks between start and end */
 > +int nvkm_pmu_allocator_block_free(struct nvkm_pmu_allocator *allocator,
 > +               u32 addr, u32 len, u32 align)
 > +{
 > +       allocator_dbg(allocator, "[in] addr %d, len %d", addr, len);
 > +
 > +       if (addr + len > allocator->limit || /* check addr range */
 > +           addr < allocator->base ||
 > +           addr & (align - 1))   /* check addr alignment */
 > +               return -EINVAL;
 > +
 > +       len = ALIGN(len, align);
 > +       if (!len)
 > +               return -EINVAL;
 > +
 > +       down_write(&allocator->rw_sema);
 > +       bitmap_clear(allocator->bitmap, addr - allocator->base, len);
 > +       up_write(&allocator->rw_sema);
 > +
 > +       allocator_dbg(allocator, "[out] addr %d, len %d", addr, len);
 > +
 > +       return 0;
 > +}
 > +

So all this code should go away when you switch to nvkm_mm. It was 
out-of-place anyway: this is a standard address space allocator and has 
nothing specific to PMU.

That's a lot of things to fix already, so I will hold my review of 
pmu/gk20a.c for next time. Just a few remarks about the most obvious 
problems though:

The file is a mess. Functions appear without any logical order, so you 
end up making declarations that could be avoided if things were ordered 
a bit better. For instance, pmu_read_message() is only used by 
pmu_process_message(), but you have 3 functions between these two. A 
logical ordering of the code makes it much easier to read: "building 
blocks" functions first, more complex functions later. Ideally you would 
end up with a C file that has no forward-declarations.

Again, some functions are absolutely not used, sometimes in worrying 
ways. Examples are gk20a_pmu_destroy and gk20a_pmu_create_, but I 
suspect there are others.

For gk20a_pmu_create_, I don't even know why it is here in the first 
place. It seems like its code should be gk20a_pmu_ctor() instead, and it 
sets function pointers that are apparently never called because they are 
remaining NULL and things seem to go just fine?

This patch should definitely be split into different bits to allow a 
more pleasant review. Right now it is almost impossible to understand 
what it does. Suggestion for splitting:

1) Add firmware loading ability, bootstrap PMU (since these two tasks 
cannot be separated I guess)
2) Add message receiving/posting ability
3) DebugFS support

This should be a good beginning to make things more readable. There are 
other things to comment on, but let's start with this.

Keep in mind that upstreaming is more than just trying to make the 
downstream code fit as-is in the upstream kernel. You need to reshape 
things when it makes sense, and replace custom-built solutions with the 
ones that already exist. Also important is to make sure you uncover 
things in a logical way, in chunks as small as possible to the 
unfamiliar reader can understand them (for this particular series I 
don't think we can go with less-than-300-lines patches though). In other 
words, it is ok to send a 3000 lines patch series, if everything appears 
progressively and logically. A 3000 lines patch however is likely to be 
frown upon.

Looking forward to seeing v2 and hopefully diving deeper into this - 
good luck!

Alex.
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

      parent reply	other threads:[~2015-03-13 10:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-11  6:33 [PATCH] pmu/gk20a: PMU boot support Deepak Goyal
     [not found] ` <1426055631-1166-1-git-send-email-dgoyal-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-03-11 17:10   ` [Nouveau] " Ilia Mirkin
     [not found]     ` <CAKb7Uvj0xMvDWjKjGzbD6Tk0NArfkh4Vjvt4eRQ8XoHgR+7bsg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-12  5:20       ` Deepak Goyal
     [not found]         ` <25b5050176544f47b0ac74d4086f145c-7W72rfoJkVm6sJks/06JalaTQe2KTcn/@public.gmane.org>
2015-03-12 22:11           ` Ilia Mirkin
     [not found]             ` <CAKb7UvgDq-FzZwAZ8VwbhaVHi4B29jXL5qjOCQ47TWfqDBDQaA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-13  1:56               ` Alexandre Courbot
2015-03-13 10:12   ` Alexandre Courbot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5502B7F1.7030700@nvidia.com \
    --to=acourbot-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
    --cc=bskeggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=dgoyal-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    --cc=gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.