[PATCH 24/24] drm/radeon: add faulty command buffer dump facilities

2012-04-26 Thread Luca Tettamanti
Hi Jerome,

On Wed, Apr 25, 2012 at 9:03 PM,   wrote:
> From: Jerome Glisse 
>
> This add a command buffer dumping facilities, that will
> dump command buffer and all associated bo that most likely
> triggered a lockup.
[cut]

I spotted this:

> +void radeon_fence_blob_faulty_ib(struct radeon_device *rdev, int ring)
> +{
> + ? ? ? struct radeon_fence *fence;
> + ? ? ? struct list_head *i;
> + ? ? ? unsigned long irq_flags;
> + ? ? ? uint32_t seq;
> +
> + ? ? ? write_lock_irqsave(>fence_lock, irq_flags);
> + ? ? ? seq = radeon_fence_read(rdev, ring);
> + ? ? ? list_for_each(i, >fence_drv[ring].emitted) {
> + ? ? ? ? ? ? ? fence = list_entry(i, struct radeon_fence, list);
> + ? ? ? ? ? ? ? if (fence->seq != seq && fence->ib) {
> + ? ? ? ? ? ? ? ? ? ? ? radeon_lockup_build_blob(rdev, fence->ib);

radeon_lockup_build_blob() will take a mutex and call vmalloc() inside
an atomic context.

Luca


[PATCH 24/24] drm/radeon: add faulty command buffer dump facilities

2012-04-25 Thread Jerome Glisse
On Wed, Apr 25, 2012 at 5:53 PM, Luca Tettamanti  wrote:
> Hi Jerome,
>
> On Wed, Apr 25, 2012 at 9:03 PM, ? wrote:
>> From: Jerome Glisse 
>>
>> This add a command buffer dumping facilities, that will
>> dump command buffer and all associated bo that most likely
>> triggered a lockup.
> [cut]
>
> I spotted this:
>
>> +void radeon_fence_blob_faulty_ib(struct radeon_device *rdev, int ring)
>> +{
>> + ? ? ? struct radeon_fence *fence;
>> + ? ? ? struct list_head *i;
>> + ? ? ? unsigned long irq_flags;
>> + ? ? ? uint32_t seq;
>> +
>> + ? ? ? write_lock_irqsave(>fence_lock, irq_flags);
>> + ? ? ? seq = radeon_fence_read(rdev, ring);
>> + ? ? ? list_for_each(i, >fence_drv[ring].emitted) {
>> + ? ? ? ? ? ? ? fence = list_entry(i, struct radeon_fence, list);
>> + ? ? ? ? ? ? ? if (fence->seq != seq && fence->ib) {
>> + ? ? ? ? ? ? ? ? ? ? ? radeon_lockup_build_blob(rdev, fence->ib);
>
> radeon_lockup_build_blob() will take a mutex and call vmalloc() inside
> an atomic context.
>
> Luca

Yeah, you right, i only compile tested, i haven't checked if it works
ok on lockup.
Thought solution for this is easy.

Cheers,
Jerome


[PATCH 24/24] drm/radeon: add faulty command buffer dump facilities

2012-04-25 Thread j.gli...@gmail.com
From: Jerome Glisse 

This add a command buffer dumping facilities, that will
dump command buffer and all associated bo that most likely
triggered a lockup.

Idea is that we go through unsignaled fence and we dump the
ib of the oldest unsignaled fence. Dumping is a 2 step process
on lockup detection we try to allocate a big object that will
old all the the current state (ib pm4 packet, bo content,
relocation table). Upon reading radeon_lockup_blob debugfs
file user will get this big blob and kernel will free memory.

Kernel side try to handle as gracefully as possible failure
such as mapping bo by not dumping such bo. Userspace tools
those need to have enough logic to handle such cases.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h|   14 -
 drivers/gpu/drm/radeon/radeon_cs.c |   20 --
 drivers/gpu/drm/radeon/radeon_device.c |3 +
 drivers/gpu/drm/radeon/radeon_fence.c  |   19 +
 drivers/gpu/drm/radeon/radeon_gart.c   |   10 ++-
 drivers/gpu/drm/radeon/radeon_ring.c   |  118 
 6 files changed, 173 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 7b2125b..c9f51be 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -241,6 +241,7 @@ struct radeon_fence {
 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
 int radeon_fence_driver_init(struct radeon_device *rdev);
 void radeon_fence_driver_fini(struct radeon_device *rdev);
+void radeon_fence_blob_faulty_ib(struct radeon_device *rdev, int ring);
 int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence 
**fence, int ring);
 int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence);
 void radeon_fence_process(struct radeon_device *rdev, int ring);
@@ -569,6 +570,10 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device 
*rdev, int crtc);
  */
 struct radeon_cs_reloc;

+#define RADEON_IB_TYPE_NONE0
+#define RADEON_IB_TYPE_CS  1
+#define RADEON_IB_TYPE_CS_VM   2
+
 struct radeon_ib {
struct radeon_sa_bo sa_bo;
uint32_tlength_dw;
@@ -579,6 +584,7 @@ struct radeon_ib {
boolis_const_ib;
unsignednrelocs;
struct radeon_cs_reloc  *relocs;
+   unsignedtype;
 };

 struct radeon_ring {
@@ -745,6 +751,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *cp, unsigne
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
 u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop);
 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
+void radeon_lockup_build_blob(struct radeon_device *rdev, struct radeon_ib 
*ib);


 /*
@@ -756,6 +763,7 @@ struct radeon_cs_reloc {
struct radeon_bo_list   lobj;
uint32_thandle;
uint32_tflags;
+   uint64_tgpu_addr;
 };

 struct radeon_cs_chunk {
@@ -1496,6 +1504,9 @@ struct radeon_device {
unsigneddebugfs_count;
/* virtual memory */
struct radeon_vm_managervm_manager;
+   uint32_t*blob;
+   unsignedblob_size_dw;
+   struct mutexblob_mutex;
 };

 int radeon_device_init(struct radeon_device *rdev,
@@ -1742,7 +1753,8 @@ void radeon_vm_unbind(struct radeon_device *rdev, struct 
radeon_vm *vm);
 int radeon_vm_bo_update_pte(struct radeon_device *rdev,
struct radeon_vm *vm,
struct radeon_bo *bo,
-   struct ttm_mem_reg *mem);
+   struct ttm_mem_reg *mem,
+   uint64_t *gpu_addr);
 void radeon_vm_bo_invalidate(struct radeon_device *rdev,
 struct radeon_bo *bo);
 int radeon_vm_bo_add(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index ecef708..0c0bcaa 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -334,6 +334,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
  struct radeon_cs_parser *parser)
 {
struct radeon_cs_chunk *ib_chunk;
+   unsigned i;
int r;

if (parser->chunk_ib_idx == -1)
@@ -369,6 +370,10 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
DRM_ERROR("Failed to synchronize rings !\n");
}
parser->ib->vm_id = 0;
+   parser->ib->type = RADEON_IB_TYPE_CS;
+   for (i = 0; i < parser->nrelocs; ++i) {
+   parser->relocs[i].gpu_addr = parser->relocs[i].lobj.gpu_offset;
+   }
r = radeon_ib_schedule(rdev, parser->ib);
if (r) {
   

[PATCH 24/24] drm/radeon: add faulty command buffer dump facilities

2012-04-25 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

This add a command buffer dumping facilities, that will
dump command buffer and all associated bo that most likely
triggered a lockup.

Idea is that we go through unsignaled fence and we dump the
ib of the oldest unsignaled fence. Dumping is a 2 step process
on lockup detection we try to allocate a big object that will
old all the the current state (ib pm4 packet, bo content,
relocation table). Upon reading radeon_lockup_blob debugfs
file user will get this big blob and kernel will free memory.

Kernel side try to handle as gracefully as possible failure
such as mapping bo by not dumping such bo. Userspace tools
those need to have enough logic to handle such cases.

Signed-off-by: Jerome Glisse jgli...@redhat.com
---
 drivers/gpu/drm/radeon/radeon.h|   14 -
 drivers/gpu/drm/radeon/radeon_cs.c |   20 --
 drivers/gpu/drm/radeon/radeon_device.c |3 +
 drivers/gpu/drm/radeon/radeon_fence.c  |   19 +
 drivers/gpu/drm/radeon/radeon_gart.c   |   10 ++-
 drivers/gpu/drm/radeon/radeon_ring.c   |  118 
 6 files changed, 173 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 7b2125b..c9f51be 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -241,6 +241,7 @@ struct radeon_fence {
 int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
 int radeon_fence_driver_init(struct radeon_device *rdev);
 void radeon_fence_driver_fini(struct radeon_device *rdev);
+void radeon_fence_blob_faulty_ib(struct radeon_device *rdev, int ring);
 int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence 
**fence, int ring);
 int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence);
 void radeon_fence_process(struct radeon_device *rdev, int ring);
@@ -569,6 +570,10 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device 
*rdev, int crtc);
  */
 struct radeon_cs_reloc;
 
+#define RADEON_IB_TYPE_NONE0
+#define RADEON_IB_TYPE_CS  1
+#define RADEON_IB_TYPE_CS_VM   2
+
 struct radeon_ib {
struct radeon_sa_bo sa_bo;
uint32_tlength_dw;
@@ -579,6 +584,7 @@ struct radeon_ib {
boolis_const_ib;
unsignednrelocs;
struct radeon_cs_reloc  *relocs;
+   unsignedtype;
 };
 
 struct radeon_ring {
@@ -745,6 +751,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *cp, unsigne
 unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg,
 u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop);
 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
+void radeon_lockup_build_blob(struct radeon_device *rdev, struct radeon_ib 
*ib);
 
 
 /*
@@ -756,6 +763,7 @@ struct radeon_cs_reloc {
struct radeon_bo_list   lobj;
uint32_thandle;
uint32_tflags;
+   uint64_tgpu_addr;
 };
 
 struct radeon_cs_chunk {
@@ -1496,6 +1504,9 @@ struct radeon_device {
unsigneddebugfs_count;
/* virtual memory */
struct radeon_vm_managervm_manager;
+   uint32_t*blob;
+   unsignedblob_size_dw;
+   struct mutexblob_mutex;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -1742,7 +1753,8 @@ void radeon_vm_unbind(struct radeon_device *rdev, struct 
radeon_vm *vm);
 int radeon_vm_bo_update_pte(struct radeon_device *rdev,
struct radeon_vm *vm,
struct radeon_bo *bo,
-   struct ttm_mem_reg *mem);
+   struct ttm_mem_reg *mem,
+   uint64_t *gpu_addr);
 void radeon_vm_bo_invalidate(struct radeon_device *rdev,
 struct radeon_bo *bo);
 int radeon_vm_bo_add(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
b/drivers/gpu/drm/radeon/radeon_cs.c
index ecef708..0c0bcaa 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -334,6 +334,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
  struct radeon_cs_parser *parser)
 {
struct radeon_cs_chunk *ib_chunk;
+   unsigned i;
int r;
 
if (parser-chunk_ib_idx == -1)
@@ -369,6 +370,10 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
DRM_ERROR(Failed to synchronize rings !\n);
}
parser-ib-vm_id = 0;
+   parser-ib-type = RADEON_IB_TYPE_CS;
+   for (i = 0; i  parser-nrelocs; ++i) {
+   parser-relocs[i].gpu_addr = parser-relocs[i].lobj.gpu_offset;
+   }
r = radeon_ib_schedule(rdev, parser-ib);
if 

Re: [PATCH 24/24] drm/radeon: add faulty command buffer dump facilities

2012-04-25 Thread Luca Tettamanti
Hi Jerome,

On Wed, Apr 25, 2012 at 9:03 PM,  j.gli...@gmail.com wrote:
 From: Jerome Glisse jgli...@redhat.com

 This add a command buffer dumping facilities, that will
 dump command buffer and all associated bo that most likely
 triggered a lockup.
[cut]

I spotted this:

 +void radeon_fence_blob_faulty_ib(struct radeon_device *rdev, int ring)
 +{
 +       struct radeon_fence *fence;
 +       struct list_head *i;
 +       unsigned long irq_flags;
 +       uint32_t seq;
 +
 +       write_lock_irqsave(rdev-fence_lock, irq_flags);
 +       seq = radeon_fence_read(rdev, ring);
 +       list_for_each(i, rdev-fence_drv[ring].emitted) {
 +               fence = list_entry(i, struct radeon_fence, list);
 +               if (fence-seq != seq  fence-ib) {
 +                       radeon_lockup_build_blob(rdev, fence-ib);

radeon_lockup_build_blob() will take a mutex and call vmalloc() inside
an atomic context.

Luca
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 24/24] drm/radeon: add faulty command buffer dump facilities

2012-04-25 Thread Jerome Glisse
On Wed, Apr 25, 2012 at 5:53 PM, Luca Tettamanti kronos...@gmail.com wrote:
 Hi Jerome,

 On Wed, Apr 25, 2012 at 9:03 PM,  j.gli...@gmail.com wrote:
 From: Jerome Glisse jgli...@redhat.com

 This add a command buffer dumping facilities, that will
 dump command buffer and all associated bo that most likely
 triggered a lockup.
 [cut]

 I spotted this:

 +void radeon_fence_blob_faulty_ib(struct radeon_device *rdev, int ring)
 +{
 +       struct radeon_fence *fence;
 +       struct list_head *i;
 +       unsigned long irq_flags;
 +       uint32_t seq;
 +
 +       write_lock_irqsave(rdev-fence_lock, irq_flags);
 +       seq = radeon_fence_read(rdev, ring);
 +       list_for_each(i, rdev-fence_drv[ring].emitted) {
 +               fence = list_entry(i, struct radeon_fence, list);
 +               if (fence-seq != seq  fence-ib) {
 +                       radeon_lockup_build_blob(rdev, fence-ib);

 radeon_lockup_build_blob() will take a mutex and call vmalloc() inside
 an atomic context.

 Luca

Yeah, you right, i only compile tested, i haven't checked if it works
ok on lockup.
Thought solution for this is easy.

Cheers,
Jerome
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel