2012-09-04 37 views
10

Tôi đã tìm thấy devm_kzalloc()kzalloc() trong trình điều khiển thiết bị. Nhưng tôi không biết khi nào/ở đâu để sử dụng các chức năng này. Bất cứ ai có thể vui lòng chỉ định tầm quan trọng của các chức năng này và cách sử dụng của chúng.Sự khác nhau giữa devm_kzalloc() và kzalloc() trong lập trình trình điều khiển linux

+1

Hi, Nếu chúng tôi sử dụng devm_kzalloc() thì không cần phải giải phóng bộ nhớ này (ref: [link] (http://docs.blackfin.uclinux.org/kernel/generated/device-drivers/re162.html)). Vì vậy, chúng ta có thể thay thế tất cả các hàm kzalloc() bằng devm_kzalloc() trong các chương trình vì chúng ta có thể giảm bớt gánh nặng giải phóng bộ nhớ được cấp phát động ...? –

+0

Tôi tin rằng [devres.txt] (https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/driver-model/devres.txt) sẽ trả lời hầu hết các câu hỏi . 'Devres.txt' sẽ là phiên bản Linux hiện tại của bạn (từ 2.6.31+). –

Trả lời

16

kzalloc() phân bổ bộ nhớ hạt nhân như kmalloc(), nhưng nó cũng không khởi tạo bộ nhớ được cấp phát. devm_kzalloc() được quản lý kzalloc(). Bộ nhớ được cấp phát với các chức năng được quản lý được liên kết với thiết bị. Khi thiết bị được tách ra khỏi hệ thống hoặc trình điều khiển cho thiết bị được tải xuống, bộ nhớ đó được giải phóng tự động. Nếu nhiều tài nguyên được quản lý (bộ nhớ hoặc một số tài nguyên khác) được cấp phát cho thiết bị, tài nguyên được phân bổ cuối cùng được giải phóng trước tiên.

Tài nguyên được quản lý rất hữu ích để đảm bảo hoạt động chính xác của trình điều khiển cho cả lỗi khởi tạo tại bất kỳ thời điểm nào và để khởi tạo thành công theo sau là loại bỏ thiết bị.

Xin lưu ý rằng tài nguyên được quản lý (cho dù đó là bộ nhớ hoặc một số tài nguyên khác) có nghĩa là được sử dụng trong mã chịu trách nhiệm cho việc thăm dò thiết bị. Chúng thường là một sự lựa chọn sai cho mã được sử dụng để mở thiết bị, vì thiết bị có thể được đóng mà không bị ngắt kết nối khỏi hệ thống. Đóng thiết bị yêu cầu giải phóng tài nguyên theo cách thủ công, điều này sẽ đánh bại mục đích của các tài nguyên được quản lý.

Bộ nhớ được phân bổ với kzalloc() phải được giải phóng với kfree(). Bộ nhớ được phân bổ với devm_kzalloc() được giải phóng tự động. Nó có thể được giải phóng với devm_kfree(), nhưng nó thường là một dấu hiệu cho thấy việc cấp phát bộ nhớ được quản lý không phù hợp với nhiệm vụ.

+1

Nó thực sự đáng nói đến là trường hợp sử dụng cho các tài nguyên được quản lý là '-> probe()' hoặc gọi lại giống nhau. Nó sẽ là xấu, ** ý tưởng tồi ** để sử dụng chúng trong callbacks như '-> open()'.Ngoài ra còn có một vấn đề với thời gian sống của các đối tượng trong trường hợp các hoạt động tập tin được sử dụng. – 0andriy

+0

Tôi đã mở rộng câu trả lời của mình để đề cập đến nó, cảm ơn bạn. Nếu có các lý do khác để tránh tài nguyên được quản lý trong mở(), vui lòng đăng liên kết. – proski

1

Nói cách đơn giản devm_kzalloc() và kzalloc() đều được dùng để cấp phát bộ nhớ trong trình điều khiển thiết bị, nhưng sự khác biệt là nếu bạn cấp phát bộ nhớ bằng kzalloc() hơn bạn phải giải phóng bộ nhớ đó khi vòng đời của trình điều khiển thiết bị đó được kết thúc hoặc khi nó được unloaded từ hạt nhân nhưng nếu bạn làm tương tự với devm_kzalloc() bạn không cần phải lo lắng về giải phóng bộ nhớ, bộ nhớ đó được giải phóng tự động bởi thư viện thiết bị chính nó.

Cả hai hiện chính xác những điều tương tự, nhưng bằng cách sử dụng devm_kzalloc ít overhead của giải phóng bộ nhớ được giải phóng từ các lập trình viên

Hãy giải thích cho bạn bằng cách đưa ra ví dụ, ví dụ đầu tiên bằng cách sử dụng kzalloc

static int pxa3xx_u2d_probe(struct platform_device *pdev) 
{ 
    int err; 
    u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);  1 
    if (!u2d) 
     return -ENOMEM; 
    u2d->clk = clk_get(&pdev->dev, NULL); 
    if (IS_ERR(u2d->clk)) { 
     err = PTR_ERR(u2d->clk);         2 
     goto err_free_mem; 
    } 
... 
    return 0; 
err_free_mem: 
    kfree(u2d); 
    return err; 
} 
static int pxa3xx_u2d_remove(struct platform_device *pdev) 
{ 
    clk_put(u2d->clk);    
    kfree(u2d);              3 
    return 0; 
} 

Trong ví dụ này bạn có thể điều này trong chức năng pxa3xx_u2d_remove(), kfree (u2d) (dòng được chỉ ra bởi 3) là có bộ nhớ trống do u2d phân phối bây giờ xem cùng mã bằng cách sử dụng devm_kzalloc()

static int pxa3xx_u2d_probe(struct platform_device *pdev) 
{ 
    int err; 
    u2d = devm_kzalloc(&pdev->dev, sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL); 
    if (!u2d) 
     return -ENOMEM; 
    u2d->clk = clk_get(&pdev->dev, NULL); 
    if (IS_ERR(u2d->clk)) { 
     err = PTR_ERR(u2d->clk); 
     goto err_free_mem; 
    } 
... 
    return 0; 
err_free_mem: 
    return err; 
} 
static int pxa3xx_u2d_remove(struct platform_device *pdev) 
{ 
    clk_put(u2d->clk); 
    return 0; 
} 

không có kfree() chức năng miễn phí vì cùng được thực hiện bằng devm_kzalloc()

Các vấn đề liên quan