s390/qdio: add helpers to manage qdio buffers
Users of qdio buffers employ different strategies to manage these buffers. The qeth driver uses huge contiguous buffers which leads to high order allocations with all their downsides. This patch provides helpers to allocate, free, and reset arrays of qdio buffers using non contiguous pages. Reviewed-by: Martin Peschke <mpeschke@linux.vnet.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
15ba2236f3
Коммит
5245c924c2
|
@ -415,6 +415,10 @@ struct qdio_brinfo_entry_l2 {
|
|||
#define QDIO_FLAG_SYNC_OUTPUT 0x02
|
||||
#define QDIO_FLAG_PCI_OUT 0x10
|
||||
|
||||
int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count);
|
||||
void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count);
|
||||
void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count);
|
||||
|
||||
extern int qdio_allocate(struct qdio_initialize *);
|
||||
extern int qdio_establish(struct qdio_initialize *);
|
||||
extern int qdio_activate(struct ccw_device *);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "qdio.h"
|
||||
#include "qdio_debug.h"
|
||||
|
||||
#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
|
||||
|
||||
static struct kmem_cache *qdio_q_cache;
|
||||
static struct kmem_cache *qdio_aob_cache;
|
||||
|
||||
|
@ -32,6 +34,57 @@ void qdio_release_aob(struct qaob *aob)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qdio_release_aob);
|
||||
|
||||
/**
|
||||
* qdio_free_buffers() - free qdio buffers
|
||||
* @buf: array of pointers to qdio buffers
|
||||
* @count: number of qdio buffers to free
|
||||
*/
|
||||
void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count)
|
||||
{
|
||||
int pos;
|
||||
|
||||
for (pos = 0; pos < count; pos += QBUFF_PER_PAGE)
|
||||
free_page((unsigned long) buf[pos]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qdio_free_buffers);
|
||||
|
||||
/**
|
||||
* qdio_alloc_buffers() - allocate qdio buffers
|
||||
* @buf: array of pointers to qdio buffers
|
||||
* @count: number of qdio buffers to allocate
|
||||
*/
|
||||
int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count)
|
||||
{
|
||||
int pos;
|
||||
|
||||
for (pos = 0; pos < count; pos += QBUFF_PER_PAGE) {
|
||||
buf[pos] = (void *) get_zeroed_page(GFP_KERNEL);
|
||||
if (!buf[pos]) {
|
||||
qdio_free_buffers(buf, count);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
for (pos = 0; pos < count; pos++)
|
||||
if (pos % QBUFF_PER_PAGE)
|
||||
buf[pos] = buf[pos - 1] + 1;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qdio_alloc_buffers);
|
||||
|
||||
/**
|
||||
* qdio_reset_buffers() - reset qdio buffers
|
||||
* @buf: array of pointers to qdio buffers
|
||||
* @count: number of qdio buffers that will be zeroed
|
||||
*/
|
||||
void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count)
|
||||
{
|
||||
int pos;
|
||||
|
||||
for (pos = 0; pos < count; pos++)
|
||||
memset(buf[pos], 0, sizeof(struct qdio_buffer));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qdio_reset_buffers);
|
||||
|
||||
/*
|
||||
* qebsm is only available under 64bit but the adapter sets the feature
|
||||
* flag anyway, so we manually override it.
|
||||
|
|
Загрузка…
Ссылка в новой задаче