Merge tag 'drm-intel-fixes-2018-10-03' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <airlied@redhat.com>
Thu, 4 Oct 2018 00:04:38 +0000 (10:04 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 4 Oct 2018 00:07:20 +0000 (10:07 +1000)
There's one fix for our zlib incomlete Z_FINISH on our error state handling,
plus a compilation warning fix and a tiny code clean up.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181003202840.GA23560@intel.com
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/i915_gpu_error.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_pci.c

index f7f2aa71d8d99f1c4fa4e4d4632adeb48ecd50f3..a262a64f562565d80642cf887788ac261991336e 100644 (file)
@@ -232,6 +232,20 @@ static bool compress_init(struct compress *c)
        return true;
 }
 
+static void *compress_next_page(struct drm_i915_error_object *dst)
+{
+       unsigned long page;
+
+       if (dst->page_count >= dst->num_pages)
+               return ERR_PTR(-ENOSPC);
+
+       page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
+       if (!page)
+               return ERR_PTR(-ENOMEM);
+
+       return dst->pages[dst->page_count++] = (void *)page;
+}
+
 static int compress_page(struct compress *c,
                         void *src,
                         struct drm_i915_error_object *dst)
@@ -245,19 +259,14 @@ static int compress_page(struct compress *c,
 
        do {
                if (zstream->avail_out == 0) {
-                       unsigned long page;
-
-                       page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
-                       if (!page)
-                               return -ENOMEM;
+                       zstream->next_out = compress_next_page(dst);
+                       if (IS_ERR(zstream->next_out))
+                               return PTR_ERR(zstream->next_out);
 
-                       dst->pages[dst->page_count++] = (void *)page;
-
-                       zstream->next_out = (void *)page;
                        zstream->avail_out = PAGE_SIZE;
                }
 
-               if (zlib_deflate(zstream, Z_SYNC_FLUSH) != Z_OK)
+               if (zlib_deflate(zstream, Z_NO_FLUSH) != Z_OK)
                        return -EIO;
        } while (zstream->avail_in);
 
@@ -268,19 +277,42 @@ static int compress_page(struct compress *c,
        return 0;
 }
 
-static void compress_fini(struct compress *c,
+static int compress_flush(struct compress *c,
                          struct drm_i915_error_object *dst)
 {
        struct z_stream_s *zstream = &c->zstream;
 
-       if (dst) {
-               zlib_deflate(zstream, Z_FINISH);
-               dst->unused = zstream->avail_out;
-       }
+       do {
+               switch (zlib_deflate(zstream, Z_FINISH)) {
+               case Z_OK: /* more space requested */
+                       zstream->next_out = compress_next_page(dst);
+                       if (IS_ERR(zstream->next_out))
+                               return PTR_ERR(zstream->next_out);
+
+                       zstream->avail_out = PAGE_SIZE;
+                       break;
+
+               case Z_STREAM_END:
+                       goto end;
+
+               default: /* any error */
+                       return -EIO;
+               }
+       } while (1);
+
+end:
+       memset(zstream->next_out, 0, zstream->avail_out);
+       dst->unused = zstream->avail_out;
+       return 0;
+}
+
+static void compress_fini(struct compress *c,
+                         struct drm_i915_error_object *dst)
+{
+       struct z_stream_s *zstream = &c->zstream;
 
        zlib_deflateEnd(zstream);
        kfree(zstream->workspace);
-
        if (c->tmp)
                free_page((unsigned long)c->tmp);
 }
@@ -319,6 +351,12 @@ static int compress_page(struct compress *c,
        return 0;
 }
 
+static int compress_flush(struct compress *c,
+                         struct drm_i915_error_object *dst)
+{
+       return 0;
+}
+
 static void compress_fini(struct compress *c,
                          struct drm_i915_error_object *dst)
 {
@@ -917,6 +955,7 @@ i915_error_object_create(struct drm_i915_private *i915,
        unsigned long num_pages;
        struct sgt_iter iter;
        dma_addr_t dma;
+       int ret;
 
        if (!vma)
                return NULL;
@@ -930,6 +969,7 @@ i915_error_object_create(struct drm_i915_private *i915,
 
        dst->gtt_offset = vma->node.start;
        dst->gtt_size = vma->node.size;
+       dst->num_pages = num_pages;
        dst->page_count = 0;
        dst->unused = 0;
 
@@ -938,28 +978,26 @@ i915_error_object_create(struct drm_i915_private *i915,
                return NULL;
        }
 
+       ret = -EINVAL;
        for_each_sgt_dma(dma, iter, vma->pages) {
                void __iomem *s;
-               int ret;
 
                ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
 
                s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
                ret = compress_page(&compress, (void  __force *)s, dst);
                io_mapping_unmap_atomic(s);
-
                if (ret)
-                       goto unwind;
+                       break;
        }
-       goto out;
 
-unwind:
-       while (dst->page_count--)
-               free_page((unsigned long)dst->pages[dst->page_count]);
-       kfree(dst);
-       dst = NULL;
+       if (ret || compress_flush(&compress, dst)) {
+               while (dst->page_count--)
+                       free_page((unsigned long)dst->pages[dst->page_count]);
+               kfree(dst);
+               dst = NULL;
+       }
 
-out:
        compress_fini(&compress, dst);
        ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
        return dst;
index f893a4e8b7831d7b214cf60ab7bcf9b058070714..8710fb18ed746cface7e9a7b2d6d6ac7cd06b2b4 100644 (file)
@@ -135,6 +135,7 @@ struct i915_gpu_state {
                struct drm_i915_error_object {
                        u64 gtt_offset;
                        u64 gtt_size;
+                       int num_pages;
                        int page_count;
                        int unused;
                        u32 *pages[0];
index 90628a47ae17f81312dff51ddbc89aff4af55654..29877969310dae65ff8f0a035285deb463c0d342 100644 (file)
@@ -3091,36 +3091,27 @@ gen11_gt_irq_handler(struct drm_i915_private * const i915,
        spin_unlock(&i915->irq_lock);
 }
 
-static void
-gen11_gu_misc_irq_ack(struct drm_i915_private *dev_priv, const u32 master_ctl,
-                     u32 *iir)
+static u32
+gen11_gu_misc_irq_ack(struct drm_i915_private *dev_priv, const u32 master_ctl)
 {
        void __iomem * const regs = dev_priv->regs;
+       u32 iir;
 
        if (!(master_ctl & GEN11_GU_MISC_IRQ))
-               return;
+               return 0;
+
+       iir = raw_reg_read(regs, GEN11_GU_MISC_IIR);
+       if (likely(iir))
+               raw_reg_write(regs, GEN11_GU_MISC_IIR, iir);
 
-       *iir = raw_reg_read(regs, GEN11_GU_MISC_IIR);
-       if (likely(*iir))
-               raw_reg_write(regs, GEN11_GU_MISC_IIR, *iir);
+       return iir;
 }
 
 static void
-gen11_gu_misc_irq_handler(struct drm_i915_private *dev_priv,
-                         const u32 master_ctl, const u32 iir)
+gen11_gu_misc_irq_handler(struct drm_i915_private *dev_priv, const u32 iir)
 {
-       if (!(master_ctl & GEN11_GU_MISC_IRQ))
-               return;
-
-       if (unlikely(!iir)) {
-               DRM_ERROR("GU_MISC iir blank!\n");
-               return;
-       }
-
        if (iir & GEN11_GU_MISC_GSE)
                intel_opregion_asle_intr(dev_priv);
-       else
-               DRM_ERROR("Unexpected GU_MISC interrupt 0x%x\n", iir);
 }
 
 static irqreturn_t gen11_irq_handler(int irq, void *arg)
@@ -3157,12 +3148,12 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
                enable_rpm_wakeref_asserts(i915);
        }
 
-       gen11_gu_misc_irq_ack(i915, master_ctl, &gu_misc_iir);
+       gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl);
 
        /* Acknowledge and enable interrupts. */
        raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, GEN11_MASTER_IRQ | master_ctl);
 
-       gen11_gu_misc_irq_handler(i915, master_ctl, gu_misc_iir);
+       gen11_gu_misc_irq_handler(i915, gu_misc_iir);
 
        return IRQ_HANDLED;
 }
index 6a4d1388ad2d39b2f972e0d1e1270bab8d3ce8df..1df3ce134cd0086de8b05cc7dc0fce4de4e91926 100644 (file)
@@ -592,7 +592,6 @@ static const struct intel_device_info intel_cannonlake_info = {
        GEN10_FEATURES, \
        GEN(11), \
        .ddb_size = 2048, \
-       .has_csr = 0, \
        .has_logical_ring_elsq = 1
 
 static const struct intel_device_info intel_icelake_11_info = {