@@ -411,6 +411,8 @@ i915_gem_shmem_pread(struct drm_device *dev,
411411 int hit_slowpath = 0 ;
412412 int prefaulted = 0 ;
413413 int needs_clflush = 0 ;
414+ struct scatterlist * sg ;
415+ int i ;
414416
415417 user_data = (char __user * ) (uintptr_t ) args -> data_ptr ;
416418 remain = args -> size ;
@@ -439,9 +441,15 @@ i915_gem_shmem_pread(struct drm_device *dev,
439441
440442 offset = args -> offset ;
441443
442- while ( remain > 0 ) {
444+ for_each_sg ( obj -> pages -> sgl , sg , obj -> pages -> nents , i ) {
443445 struct page * page ;
444446
447+ if (i < offset >> PAGE_SHIFT )
448+ continue ;
449+
450+ if (remain <= 0 )
451+ break ;
452+
445453 /* Operation in this page
446454 *
447455 * shmem_page_offset = offset within page in shmem file
@@ -452,7 +460,7 @@ i915_gem_shmem_pread(struct drm_device *dev,
452460 if ((shmem_page_offset + page_length ) > PAGE_SIZE )
453461 page_length = PAGE_SIZE - shmem_page_offset ;
454462
455- page = obj -> pages [ offset >> PAGE_SHIFT ] ;
463+ page = sg_page ( sg ) ;
456464 page_do_bit17_swizzling = obj_do_bit17_swizzling &&
457465 (page_to_phys (page ) & (1 << 17 )) != 0 ;
458466
@@ -731,6 +739,8 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
731739 int hit_slowpath = 0 ;
732740 int needs_clflush_after = 0 ;
733741 int needs_clflush_before = 0 ;
742+ int i ;
743+ struct scatterlist * sg ;
734744
735745 user_data = (char __user * ) (uintptr_t ) args -> data_ptr ;
736746 remain = args -> size ;
@@ -765,10 +775,16 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
765775 offset = args -> offset ;
766776 obj -> dirty = 1 ;
767777
768- while ( remain > 0 ) {
778+ for_each_sg ( obj -> pages -> sgl , sg , obj -> pages -> nents , i ) {
769779 struct page * page ;
770780 int partial_cacheline_write ;
771781
782+ if (i < offset >> PAGE_SHIFT )
783+ continue ;
784+
785+ if (remain <= 0 )
786+ break ;
787+
772788 /* Operation in this page
773789 *
774790 * shmem_page_offset = offset within page in shmem file
@@ -787,7 +803,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
787803 ((shmem_page_offset | page_length )
788804 & (boot_cpu_data .x86_clflush_size - 1 ));
789805
790- page = obj -> pages [ offset >> PAGE_SHIFT ] ;
806+ page = sg_page ( sg ) ;
791807 page_do_bit17_swizzling = obj_do_bit17_swizzling &&
792808 (page_to_phys (page ) & (1 << 17 )) != 0 ;
793809
@@ -1633,6 +1649,7 @@ static void
16331649i915_gem_object_put_pages_gtt (struct drm_i915_gem_object * obj )
16341650{
16351651 int page_count = obj -> base .size / PAGE_SIZE ;
1652+ struct scatterlist * sg ;
16361653 int ret , i ;
16371654
16381655 BUG_ON (obj -> madv == __I915_MADV_PURGED );
@@ -1653,19 +1670,21 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
16531670 if (obj -> madv == I915_MADV_DONTNEED )
16541671 obj -> dirty = 0 ;
16551672
1656- for (i = 0 ; i < page_count ; i ++ ) {
1673+ for_each_sg (obj -> pages -> sgl , sg , page_count , i ) {
1674+ struct page * page = sg_page (sg );
1675+
16571676 if (obj -> dirty )
1658- set_page_dirty (obj -> pages [ i ] );
1677+ set_page_dirty (page );
16591678
16601679 if (obj -> madv == I915_MADV_WILLNEED )
1661- mark_page_accessed (obj -> pages [ i ] );
1680+ mark_page_accessed (page );
16621681
1663- page_cache_release (obj -> pages [ i ] );
1682+ page_cache_release (page );
16641683 }
16651684 obj -> dirty = 0 ;
16661685
1667- drm_free_large (obj -> pages );
1668- obj -> pages = NULL ;
1686+ sg_free_table (obj -> pages );
1687+ kfree ( obj -> pages ) ;
16691688}
16701689
16711690static int
@@ -1682,6 +1701,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
16821701 return - EBUSY ;
16831702
16841703 ops -> put_pages (obj );
1704+ obj -> pages = NULL ;
16851705
16861706 list_del (& obj -> gtt_list );
16871707 if (i915_gem_object_is_purgeable (obj ))
@@ -1739,6 +1759,8 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
17391759 struct drm_i915_private * dev_priv = obj -> base .dev -> dev_private ;
17401760 int page_count , i ;
17411761 struct address_space * mapping ;
1762+ struct sg_table * st ;
1763+ struct scatterlist * sg ;
17421764 struct page * page ;
17431765 gfp_t gfp ;
17441766
@@ -1749,20 +1771,27 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
17491771 BUG_ON (obj -> base .read_domains & I915_GEM_GPU_DOMAINS );
17501772 BUG_ON (obj -> base .write_domain & I915_GEM_GPU_DOMAINS );
17511773
1752- /* Get the list of pages out of our struct file. They'll be pinned
1753- * at this point until we release them.
1754- */
1774+ st = kmalloc (sizeof (* st ), GFP_KERNEL );
1775+ if (st == NULL )
1776+ return - ENOMEM ;
1777+
17551778 page_count = obj -> base .size / PAGE_SIZE ;
1756- obj -> pages = drm_malloc_ab (page_count , sizeof (struct page * ));
1757- if (obj -> pages == NULL )
1779+ if (sg_alloc_table (st , page_count , GFP_KERNEL )) {
1780+ sg_free_table (st );
1781+ kfree (st );
17581782 return - ENOMEM ;
1783+ }
17591784
1760- /* Fail silently without starting the shrinker */
1785+ /* Get the list of pages out of our struct file. They'll be pinned
1786+ * at this point until we release them.
1787+ *
1788+ * Fail silently without starting the shrinker
1789+ */
17611790 mapping = obj -> base .filp -> f_path .dentry -> d_inode -> i_mapping ;
17621791 gfp = mapping_gfp_mask (mapping );
17631792 gfp |= __GFP_NORETRY | __GFP_NOWARN ;
17641793 gfp &= ~(__GFP_IO | __GFP_WAIT );
1765- for ( i = 0 ; i < page_count ; i ++ ) {
1794+ for_each_sg ( st -> sgl , sg , page_count , i ) {
17661795 page = shmem_read_mapping_page_gfp (mapping , i , gfp );
17671796 if (IS_ERR (page )) {
17681797 i915_gem_purge (dev_priv , page_count );
@@ -1785,20 +1814,20 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
17851814 gfp &= ~(__GFP_IO | __GFP_WAIT );
17861815 }
17871816
1788- obj -> pages [ i ] = page ;
1817+ sg_set_page ( sg , page , PAGE_SIZE , 0 ) ;
17891818 }
17901819
17911820 if (i915_gem_object_needs_bit17_swizzle (obj ))
17921821 i915_gem_object_do_bit_17_swizzle (obj );
17931822
1823+ obj -> pages = st ;
17941824 return 0 ;
17951825
17961826err_pages :
1797- while (i -- )
1798- page_cache_release (obj -> pages [i ]);
1799-
1800- drm_free_large (obj -> pages );
1801- obj -> pages = NULL ;
1827+ for_each_sg (st -> sgl , sg , i , page_count )
1828+ page_cache_release (sg_page (sg ));
1829+ sg_free_table (st );
1830+ kfree (st );
18021831 return PTR_ERR (page );
18031832}
18041833
@@ -2981,7 +3010,7 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj)
29813010
29823011 trace_i915_gem_object_clflush (obj );
29833012
2984- drm_clflush_pages (obj -> pages , obj -> base . size / PAGE_SIZE );
3013+ drm_clflush_sg (obj -> pages );
29853014}
29863015
29873016/** Flushes the GTT write domain for the object if it's dirty. */
@@ -3731,6 +3760,8 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
37313760 i915_gem_object_put_pages (obj );
37323761 i915_gem_object_free_mmap_offset (obj );
37333762
3763+ BUG_ON (obj -> pages );
3764+
37343765 drm_gem_object_release (& obj -> base );
37353766 i915_gem_info_remove_obj (dev_priv , obj -> base .size );
37363767
0 commit comments