1. Trang chủ
  2. » Luận Văn - Báo Cáo

Chương trình sửa mã nguồn hệ điều hành Linux báo cáo dung lượng Ram và thu hồi bộ nhớ theo cơ chế slab cache

37 560 2
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Chương trình sửa mã nguồn hệ điều hành Linux báo cáo dung lượng Ram và thu hồi bộ nhớ theo cơ chế slab cache
Tác giả Lương Kim Doanh, Ngô Quang Thìn, Trần Hoàng Điệp, Nguyễn Trung Thành
Người hướng dẫn Phạm Văn Tiến
Trường học Trường Đại Học Bách Khoa Hà Nội
Chuyên ngành Hệ Điều Hành
Thể loại Báo cáo bài tập dài
Năm xuất bản 2011
Thành phố Hà Nội
Định dạng
Số trang 37
Dung lượng 1,57 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Trường Đại Học Bách Khoa Hà Nội Viện Điện Tử Viễn Thông ====o0o==== BÁO CÁO BÀI TẬP DÀI MÔN HỆ ĐIỀU HÀNH Bài tập số 2: Chương trình sửa mã nguồn hệ điều hành Linux báo cáo dung lượng Ram và thu hồi bộ nhớ theo cơ chế slab cache Giáo viên hướng dẫn : PHẠM VĂN TIẾN Sinh viên thực hiện : Lương Kim Doanh Ngô Quang Thìn Trần Hoàng Điệp Nguyễn Trung Thành Lớp : KSTNĐTVTK52 HÀ NỘI 102011 Mục Lục: I.Giới thiệu 3 1.Giới thiệu chung 3 2. Giới thiệu slab cache 4 3. Object: 17 3.1. Khởi tạo object trong slab: 17 3.2. Cấp phát object: 17 3.3. Giải phóng object: 17 4. PerCPU object cache: 18 4.1. Cho phép CPU cache: 18 4.2. Cập nhật thông tin mỗi CPU: 18 4.3. Drainning a PerCPU cache: 19 4.4. Khởi tạo Slab allocator: 19 5. Giao tiếp với Buddy allocator: 19 III. Triển khai. 20 1. Giới thiệu thư mụcprocsys. 20 2. Linux Modules 22 2.1 Xây dựng Module 22 2.2 Exported Symbols 24 IV. Các module mã nguồn chỉnh sửa và thêm 29 1. Mục đích 29 2. Chi tiết 29 2.1. File kernel_sysctl.c 29 2.2. Sửa file sysctl.c 31 2.3. File KSTNDTVTK52.c 32 2.4. Sửa file Makefile 32 V. Kiểm thử và kết quả 32 1. Hiển thị 32 2.Test module 35 I.Giới thiệu 1.Giới thiệu chung Mục đích của việc quản lí bộ nhớ là cung cấp một phương thức trong đó bộ nhớ có thể được chia sẻ động giữa những người sử dụng, những tiến trình khác nhau với những mục đích khác nhau. Phương thức quản lí bộ nhớ sẽ thực hiện hai nhiệm vụ: Tối thiểu lượng thời gian yêu cầu quản lí bộ nhớ

Trang 1

Trường Đại Học Bách Khoa Hà Nội

Viện Điện Tử Viễn Thông

====o0o====

BÁO CÁO BÀI TẬP DÀI MÔN HỆ

ĐIỀU HÀNH

Bài tập số 2:

Chương trình sửa mã nguồn hệ điều hành Linux báo cáo dung lượng

Ram và thu hồi bộ nhớ theo cơ chế slab cache

Giáo viên hướng dẫn : PHẠM VĂN TIẾN Sinh viên thực hiện : Lương Kim Doanh

Trang 2

Mục Lục: I.Giới thiệu 3

1.Giới thiệu chung 3

2 Giới thiệu slab cache 4

3 Object: 17

3.1 Khởi tạo object trong slab: 17

3.2 Cấp phát object: 17

3.3 Giải phóng object: 17

4 Per-CPU object cache: 18

4.1 Cho phép CPU cache: 18

4.2 Cập nhật thông tin mỗi CPU: 18

4.3 Drainning a Per-CPU cache: 19

4.4 Khởi tạo Slab allocator: 19

5 Giao tiếp với Buddy allocator: 19

III Triển khai 20

1 Giới thiệu thư mục/proc/sys 20

2 Linux Modules 22

2.1 Xây dựng Module 22

2.2 Exported Symbols 24

IV Các module mã nguồn chỉnh sửa và thêm 29

1 Mục đích 29

2 Chi tiết 29

2.1 File kernel_sysctl.c 29

2.2 Sửa file sysctl.c 31

2.3 File KSTN-DTVT-K52.c 32

2.4 Sửa file Makefile 32

V Kiểm thử và kết quả 32

1 Hiển thị 32

2.Test module 35

Trang 3

I.Giới thiệu

1.Giới thiệu chung

Mục đích của việc quản lí bộ nhớ là cung cấp một phương thức trong đó bộ nhớ có thể được chia sẻ động giữa những người sử dụng, những tiến trình khác nhau với những mục đích khác nhau Phương thức quản lí bộ nhớ sẽ thực hiện hai nhiệm vụ:

- Tối thiểu lượng thời gian yêu cầu quản lí bộ nhớ

- Lượng bộ nhớ sử dụng sẵn có là lớn nhất (tối thiểu lượng nhớ tiêu tốn cho quản lí)Việc quản lí bộ nhớ lý tưởng là thực hiện tốt cả hai nhiệm vụ trên, nhưng thực tế không

dễ dàng thực hiện chúng cùng một lúc và chùng thường có xu hướng mâu thuẫn với nhau.Chúng ta có thể phát triển một thuật toán mà sử dụng ít bộ nhớ nhưng sẽ phải mất nhiều thời gian để quản lí bộ nhớ sẵn có Chùng ta cũng có thể phát triển một thuật toán mà quản lí bộ nhớ một cách hiệu quả về thời gian nhưng sẽ tốn nhiều tài nguyên hệ thống hơn Kết cục một ứng dụng cụ thể chỉ ưu tiên chọn một trong hai xu hướng phú hợp nhất

Việc quản lí bộ nhớ trước đây dựa vào chiến lược cấp phát dựa vào heap Trong phương thức này một khối bộ nhớ lớn (người ta gọi la heap) được sử dụng để cấp bộ nhớ cho mục đích của người sử dụng Khi người sử dụng cần một khối bộ nhớ, họ yêu cầu heap manager tìm kiếm lượng bộ nhớ thoả mãn và trả về khối tìm được Một vài thuật toán được sử dụng để tìm kiếm là first-fit (khối đấu tiên tìm được trong heap thỏa mãn yêu cầu) Khi người sử dụng hoàn tất công việc, khối bộ nhớ đươc trả lại cho heap

Vấn đề chủ yếu phát sinh với chiến lược cấp phát dựa vào heap này là sự phân mảnh (fragmentation) Khi khối bộ nhớ được cấp phát, chúng sau đó được trả lại theo thứ

tự khác nhau vào những thời điểm khác nhau Điều này dẫn đến việc để lại những chỗ trống trong heap, yêu cầu nhiếu thời gian hơn để quản lí bộ nhớ rỗi Thuật toán này hường đến việc quản lí tài nguyên bộ nhớ một cách hiệu quả nhưng yêu cầu thời gian để quản lí heap

Một phương pháp khác là cấp phát bộ nhớ theo kiểu bè bạn (buddy memory allocation), là kĩ thuất cấp phát nhanh hơn mà chia bộ nhó thành các phân vùng

(partition) mũ cơ số 2 và thử cấp phát bộ nhớ yêu cấu sử dụng phương pháp best-fit Khi

bộ nhớ cấp phát cho ngưới sử dụng được giải phóng, khối buddy được kiểm tra để xem

Trang 4

liệu bất kì hàng xóm nào của nó đang rỗi hay không Nếu có, những khối nhớ này được hợp lại để giảm những lãng phí bộ nhớ do phương pháp best-fit

2 Giới thiệu slab cache

Bộ cấp phát slab được sử dụng trong Linux dựa vào thuật toán được giới thiệu bởiJeff Bonwick cho hệ điều hành SunOS Giải pháp cấp phát của Jeff Bonwick xoay quanh việc đệm đối tượng (object caching) Bên trong kernel, một lượng đáng kể bộ nhớ được cấp phát cho một tập hữu hạn các đối tượng như miêu tả tập tin ( file descriptor) và các cấu trúc thông dụng khác Jeff nhận thấy rằng thời gian cần thiết để khởi tạo một object thông thường trong kernel vượt quá thời gian cần thiết để cấp phát và giải phóng nó Jeff đưa ra kết luận rằng thay vì giải phóng bộ nhớ trả lại global pool, ta nên để bộ nhớ duy trìtrạng thái khởi tạo cho mục đích sử dụng nó Ví dụ, nếu bộ nhớ được cấp phát cho mutex.Những lần cấp phát sau của bộ nhớ không càn thực hiện khởi tạo vì nó đã ở trạng thái mong muốn từ lần giải cấp phát trước (deallocation) và gọi đến hàm hủy (deconstructor)

Bộ cấp phát slab sử dụng ý tưởng này và nhiều ý tưởng khác để xây dựng một bộ cấp phát hiệu quả về không gian và thời gian

Slab allocator chứa một số cache mà liên kết với nhau bằng danh sách liên kết vòng đôi (doubly linked circular list) gọi là cache main Một cahe, trong ngữ cảnh slab allocator, là một

Trang 5

- Cấp phát những khối bộ nhớ nhỏ để giúp loại bỏ phân mảnh nội gây ra bởi hệ thống buddy

- Đệm những đối tượng thường sử dụng sao cho hệ thống phải tốn thời gian khởi tạo, cấp phát, hủy đối tượng

- Sắp xếp những object trong cache L1 và L2 để sử dụng hardware cache tốt hơn

II: Nội dung

1.Cache:

Mỗi cache tồn tại cho 1 kiểu object mà được đệm Danh sách đầy đủ những cache hiện cólúc hệ thống đang chạy có thể được liệt kê sử dụng lệnh: cat/proc/slabinfo

Trang 6

Mỗi cột tương ứng với 1 trường của cấu trúc kmem_cache:

name: tên cache mà người sử dụng có thể đọc được VD:TCPv6

active_objs: số lượng object đang sử dụng

num_objs: tổng số lượng object có thể sử dụng được bao gồm cả những object chưa được sử dụng

objsize: kích thước của object trong cache

active_slabs : số lượng slab đang được sử dụng của cache

num_clabs: số lượng slab cấp phát cho cache

Nếu SMP được enable thì thêm 2 trường nữa được thêm vào:

- limit: Số lượng free object mà pool (object pools) có thể có trước khi một nửa được trả lại cho global pool

- batchcount: là số lượng object được cấp phát cho CPU khi không có object free

Trang 7

Để tăng tốc cấp phát và giải phóng object và slab , chúng được chia a thành ba danh sách : slabs_full, slabs_partial và slab_free Tất cả các object trong slabs_full đã được sử dụng, slabs_partial có object, vì vậy được dung chủ yếu cho việc cấp phát đối tượng, slabs_free không

có đối tượng nào được cấp phát, vì vậy được dung chủ yếu cho việc hủy slab

1.1.Cache Descriptor:

Tất cả thông tin về 1 cache được lưu trong cấu trúc kmem_cache được khai báo trong Include/linux/slub_def.h (nếu kernel sử dụng SLUB thì cấu trúc này nằm trong file include/linux/slub_def.h)

1.2.Những cờ static của cache:

SLUB_HWCACHE_ALIGN: đặt object vào L1 CPU cache

SLUB_CACHE_DMA: cấp phát slab từ vùng nhớ ZONE_DMA

Nếu tùy chọn CÒNIG_SLAB_DEBUG được set sẽ có thêm 1 số tùy chọn:

SLAB_DEBUG_FREE: khi thi hành việc kiểm tra object free

SLAB_RED_ZONE: đánh dấu object đầu và object cuối và bẫy tràn

SLAB_POISON : “nhiễm độc” object làm cho nó không được cấp phát hay khởi tạo

Để ngăn việc sử dụng sai các cờ, một CREATE_MASK được tạo ra trong mm/slab.c chứa tất cả các cở được cho phép Khi một cache được tạo ra, các cờ yêu cầu được so sánh với CREATE_MASK và được coi như là một lỗi nếu sử dụng sai cờ

1.3 Cache coloring:

Để sử dụng hardware cache tốt hơn, slab allocator sẽ dịch (offset) object trong các slab khác nhau các khoảng khác nhau phụ thuộc vào khoảng trống còn lại trong slab Độ dịch được tính theo đơn vị BYTES_PER_WORD nếu SLAB_HWCACHE_ALIGN không được set, được tính theo L1_CACHE_BYTES nếu SLAB_HWCACHE_ALIGN được set

Sau quá trình tạo cache, object trong slab được cấp phát, phần dư được sử dụng để dịch các object (cache coloring) Hai số được khai báo trong cấu trúc kmem_cache liên quan đến việc dịch object:

Colour:số lần dịch có thể đối với một bộ dịch

Colour_off: độ dịch

Ví dụ, để thuận tiện, giả sử s_mem ( địa chỉ object đầu tiên) trên slab là 0 và có 100 byte

dư trên lab và độ dịch là 32 byte trên L1 cache trên một Pentium II Trong kịch bản này,

Trang 8

object của slab đầu tiên đựoc tạo ra bắt đầu từ 0 Object của slab thứ 2 sẽ bắt đầu ở byte 32, object của slab thứ 3 sẽ bắt đầu ở byte 64, object của slab thứ 4sẽ bắt đầu ở byte 96, và object của slab thứ 5sẽ bắt đầu ở byte 0 Với cách dịch như vậy, các object từ mỗi slab sẽ không bị cache hit trên cùng 1 line Giá trị của colour =3, colour_off= 32

1.4.Tạo cache:

Hàm kem_cache_create () có nhiệm vụ tạo cache mới và thêm nó vào cache chain

Công việc tạo cache được thực hiện như sau:

Thi hành việc kiểm tra cơ bản cho việc sử dụng sai

Thực hiện kiểm tra debug nếu CONFIG_SLAB_DEBUG được set

Cấp phát một kmem_cache từ cache_cache slab cache

Chỉnh kích cỡ object đến kích cỡ word

Tính toán xem có bao nhiêu object sẽ điền đủ một slab

Chỉnh kích cỡ đối tượng theo L1

Tính toán color

Khởi tạo những trường hợp còn lại của cache descriptor

Thêm cache mới vào cache chain

1.5 Cache reaping :

Trang 9

1.6 Cache shrinking :

Khi một cache được chọn để shrink chính nó, những bước sau được thực hiện :

delete hết tất cả các object trong mỗi CPU cache

delete tất cả các slab từ slabs_free nếu cờ grow không được set

Trang 10

Kmem_cache_shrink() xóa tất cả các slab từ slabs_free và trả lại số page được giải phóng , hàm

cơ sở này được export cho những người sử dụng slab allocator

Trang 11

Hàm thứ hai,_kmem_cache_shrink() giải phóng tất cả các slab từ slabs_free và sau đó kiểm tra lại xem slabs_partial và slabs_full có rỗng khống Hàm này chỉ được sử dụng bên trong module và rất quan trọng khi hủy cache, nó không quan tâm số page được giải phóng chỉ miễn làcache rỗng

1.7 Cache Destroying:

Khi 1 mode unload, nó có trách nhiệm phải xóa bỏ bất kì cache nào với hàm

kmem_cache_destroy() Mã nhân kennel không chủ động destroy cache của nó bởi vì sự tồn tại của chúng là cần thiết cho hệ thống Những bước được thực hiện để xóa bỏ cache:

Delete cache từ cache chain

Shrink cache để delete tất cả các slab

giải phogns bất kì cache của mỗi CPU (kfree())

Delete cache descriptor từ cache_cache

1.8: Kích cỡ cache:

Linux duy trì hai tập hợp cache dùng cho việc cấp phát lượng bộ nhớ nhỏ mà bình thườngcấp phát page không phù hợp.Một tập hợp được sử dụng cho DMA, và tập hợp còn lại phù hợp với sử dụng thông thường Tên mà người sử dụng có thể đọc được là cache cỡ -N và cache cỡ -N(DMA) Thông tin về kích cỡ cache được lưu trong cấu trúc cache_sizes

Cs_size: kích cỡ của khối bộ nhớ

Cs_cachep: cache của các khối dùng cho việc sử dụng bộ nhớ thông thường

Trang 12

Cs dmacachep: cache của các khối dùng cho việc sử dụng DMA

Bời vì số lượng các cache trong hệ thống là giới hạn, một dãy kích cỡ cache tĩnh được khởi tạo tại thời điểm biên dịch, bắt đầu với 32 bytes trên máy dùng page có kích cỡ 4KB và 64KB với kích cỡ trang lớn hơn:

Trang 13

truct list_head list;

unsigned long colouroff;

void *s_mem; /* bao gồm colour offset*/

unsigned int inuse; /* số lượng object đang được sử dụng trong slab */

kmem_bufctl_t free

unsigned short nodeid;}

list : đây là danh sách liên kết của slab (slabs_free, slabs_partial, slabs_full)

colouroff: độ dịch từ địa chỉ cơ sở của object đầu tiên trong slab

free: đây là 1 dãy bufctl được sử dụng để lưu vị trí của free object

Cấu trúc quản lý slab được giữ trong ( khi cờ CFLGS_OFF_SLAB được clear) hoặc nằm ngòai slab

Trang 14

2.1 Lưu trữ slab Descriptor:

Nếu kích cỡ object lớn hơn 1 ngưỡng ( 512 byte đối với x86), CFLGS_OFF_SLAB được set và slab descriptor được giữ ngòai slab ở 1 trong những kích cỡ cache Kích cỡ cache là đủ lớn để chứa cấu trúc slab, và dãy kmem_bufctl_t Cách khác là lưu trữ cấu trúc slab và dãy

kmem_bufclt_t trong slab Dãy kmem_bufctl_t giữ chỉ số của những object chưa được cấp phát, sẵn sàng được sử dụng khi cần thiết

Trang 15

Những tác vụ được thực hiện để tạo slab như sau :

.Thực thi những kiểm tra cơ sở để đảm bảo không có sử dụng sai

Tính toán color offset cho object trong slab

Cấp phát bộ nhớ cho slab và slab descriptor

Liên kết những page được sử dụng cho slab đến slab và cache descriptor

.Khởi tạo object trong slab

.Thêm slab đến cache

2.3 Tracking free object:

Trang 16

Slab allocator có 1 phương pháp đơn giản và nhanh chóng xác định chỗ của object rỗi Object thuộc về slab và cache được xác định bằng cấu truc page và dãy kmem_bufctl_t, một dãy

số nguyên các chỉ số của object Số phần tử này bằng số object trong slab

typedef unsigned int kmem_bufctl_t;

Bởi vì dãy này đứng sau slab descriptor và không có con trỏ trực tiếp đến phần tử đầu tiên một cách trực tiếp, một macro trợ giúp được khai báo

static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)

{

return (kmem_bufctl_t*)(slabp+1);

}

Khi cấp phát một object, kmem_cache_alloc() thực hiện công việc câp nhật dãy

kmem_bufctl () Trường slab free giữ chỉ số của free object đầu tiên, chỉ số free object tiếp theo là kmem_bufctl_t [slabfree] diễn giải như sau:

objp= slabp->_mem+ slabp->free*cachep-> objsize;

slabp->free= slab_bufctl (slabp) [slabp-> free];

2.4 Tính toán số object trong 1 Slab:

Trong quá trình tạo cache, hàm cache_ estimate() được gọi để tính xem có bao nhiêu object được lưu trên 1 slab, tính trong 2 trường hợp slab descriptor được lưu trong hay ngoài slab

và kích cỡ của kmem_bufctl_t cần được track nếu 1 object là rỗi hay không Nó trả lại số object

có thể chứa được và số byte lãng phí Số byte lãng phí có ý nghĩa quan trọng nếu cache coloring được sử dụng Tính toán này được thực hiện theo những bước sau:

.Khởi tạo số byte lãng phí bằng tổng kích cỡ slab, nghĩa là PAGE_SIZEgfporder

Trừ đi lượng không gian yêu cầu để lưu slab descriptor

.Đếm số lượng object có thể được lưu bao gồm kích thước của kmem_bufctl_t nếu slab

descriptor được lưu ở trong slab Tiếp tục tăng kích cỡ cho tới khi slab được điền đầy

Trả lại số object và số byte lãng phí

2.5 Slab Destroying:

Trang 17

Khi một cache bị shring hay destroy, slab bị delete Bởi vị object có thể có hàm hủy (destructor) hàm này phải được gọi Các công việc để delete một slab như sau:

Nếu có thể, gọi hàm destructor cho mọi object trong slab

Nếu debug được enable , kiểm tra vết red_zone và poison

Giải phóng page của slab sử dụng

Trang 18

3 Object:

3.1 Khởi tạo object trong slab:

Khi slab được tạo ra, tất cả object bên trog nó được đặt ở trong một trạng thái khởi tạo Nếu hàm khởi tạo (constructor) sử dụng được, nó được gọi cho mỗi object và người ta mong muốn object được giữ ở trạng thái khởi tạo lúc giải phóng

để tạo ra slab mới trong danh sách slabs_free Bước cuối cùng là cấp phát object từ slab đã chọn

Trong trường hợp SMP, ta thực hiện thêm một bước nữa Trước khi cấp phát một object, slab allocator sẽ kiểm tra xem nếu có một object có thể sử dụng tu per-CPU cache và sẽ sử dụng nếu có Nếu không có, nó sẽ cấp phát một số batchcount các object trong một khối và đặt chúng vào per-CPU cache của nó

3.3 Giải phóng object:

Kmem cache free() được sử dụng để giải phóng object và tác vụ của nó tương đối đơn giản Giống như kmem_cache_alloc(), hoạt động của kmem_cache_free() khác nhau trong hai trường hợp UP và SMP Sự khác nhau cơ bản giữa hai trường hợp là ở chỗ, trong trường hợp của

UP, object được trả lại trực tiếp cho slab nhưng trong trường hợp của SMP, object được trả lại cho per-CPU cache Trong cả hai trường hợp, hàm hủy (destructor) cho object sẽ được gọi nếu

có thể Hàm hủy có nhiệm vụ trả object về trạng thái khởi tạo

4 Per-CPU object cache:

Một trong những tác vụ mà slab allocator đảm nhiệm là tăng hiệu suất sử dụng cache cứng Mục đích của việc tính toán hiêụ năng cao nhìn chung là sử dụng dữ liệu trên cùng một CPU lâu nhất có thể Linux thưc hiên điều này bằng cách cố gắng giữ object trong cùng một CPU cache với per-CPU object cache, đơn giản được gọi là cpu cache cho mỗi cpu trên hệ thống Khi cấp phát hay giải phóng object, chúng được đặt ở cpu cache Khi không có object nàođược giải phóng, một nhóm object được đặt vào trong pool Khi pool trở nên quá lớn, một nửa bịloại và đặt vào global cache Với cách này, cache cứng trên cùng một CPU sẽ được sử dụng lâu nhất có thể Lợi ích thứ hai cưa phương pháp này là không phải sử dụng spinlock khi CPU truy cập pool bởi vì CPU sẽ không thể truy cập được dữ liệu cục bộ khi object đã được gán cho CPU này

Ngày đăng: 13/06/2014, 13:31

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w