0029
RULE_ERROR
Leaving allocated memory units in the coherent-memory pool being freed
Summary
All allocated memory in a pool should be freed before destroying the pool.
Description
Adherence to this rule prevents possible driver errors related to release of memory regions, which are still being used.
Memory pools are released by calling dma_pool_destroy(struct dma_pool* pool) or pci_pool_destroy(struct pci_pool* pool) functions. However, before memory pools can be released, the memory in them should be deallocated.
dma_pool_destroy(struct dma_pool* pool)
pci_pool_destroy(struct pci_pool* pool)
Therefore, for each pool, all memory regions allocated by dma_pool_alloc() or pci_pool_alloc() should be released by dma_pool_free() or pci_pool_free() before the appropriate destroy function is applied to the pool in subject.
dma_pool_alloc()
pci_pool_alloc()
dma_pool_free()
pci_pool_free()
destroy
Example
Correct usage example:
int some_kernel_ehci_module_func(/*non-important data type*/ ehci) { struct ehci_qtd *qtd; dma_addr_t dma; ehci->qtd_pool = pci_pool_create ("ehci_qtd", ehci->hcd.pdev, sizeof (struct ehci_qtd), 32 /* byte alignment */, 4096 /* can't cross 4K */, flags); if (!ehci->qtd_pool) { //Some error handling! } //Some non-important code stuff qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma); //Simple trying to alloc some memory portion from our pci-pool if (qtd != 0) { memset (qtd, 0, sizeof *qtd); qtd->qtd_dma = dma; //Working with allocated structure data qtd->hw_next = EHCI_LIST_END; //With another one... qtd->hw_alt_next = EHCI_LIST_END; INIT_LIST_HEAD (&qtd->qtd_list); } //Here, we need to free our allocated memory portion, //because pci-pool need to be destroyed pci_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma); //Now, if all is OK, we can destroy our pci-pool if (ehci->qtd_pool) pci_pool_destroy (ehci->qtd_pool); ehci->qtd_pool = 0; }
Notes
Examples of kernel drivers for verification:
drivers/block/DAC960.c
drivers/ieee1394/ohci1394.c
drivers/infiniband/hw/mthca/mthca_av.c
drivers/usb/gadget/net2280.c