static atomic_t spare_indicator_usecount;
#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2
static mempool_t *qdio_mempool_scssc;
+static struct kmem_cache *qdio_q_cache;
static debug_info_t *qdio_dbf_setup;
static debug_info_t *qdio_dbf_sbal;
qdio_release_irq_memory(struct qdio_irq *irq_ptr)
{
int i;
+ struct qdio_q *q;
- for (i=0;i<QDIO_MAX_QUEUES_PER_IRQ;i++) {
- if (!irq_ptr->input_qs[i])
- goto next;
-
- kfree(irq_ptr->input_qs[i]->slib);
- kfree(irq_ptr->input_qs[i]);
-
-next:
- if (!irq_ptr->output_qs[i])
- continue;
-
- kfree(irq_ptr->output_qs[i]->slib);
- kfree(irq_ptr->output_qs[i]);
-
+ for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) {
+ q = irq_ptr->input_qs[i];
+ if (q) {
+ free_page((unsigned long) q->slib);
+ kmem_cache_free(qdio_q_cache, q);
+ }
+ q = irq_ptr->output_qs[i];
+ if (q) {
+ free_page((unsigned long) q->slib);
+ kmem_cache_free(qdio_q_cache, q);
+ }
}
- kfree(irq_ptr->qdr);
+ free_page((unsigned long) irq_ptr->qdr);
free_page((unsigned long) irq_ptr);
}
{
int i;
struct qdio_q *q;
- int result=-ENOMEM;
-
- for (i=0;i<no_input_qs;i++) {
- q = kzalloc(sizeof(struct qdio_q), GFP_KERNEL);
- if (!q) {
- QDIO_PRINT_ERR("kmalloc of q failed!\n");
- goto out;
- }
+ for (i = 0; i < no_input_qs; i++) {
+ q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
+ if (!q)
+ return -ENOMEM;
+ memset(q, 0, sizeof(*q));
- q->slib = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
if (!q->slib) {
- QDIO_PRINT_ERR("kmalloc of slib failed!\n");
- goto out;
+ kmem_cache_free(qdio_q_cache, q);
+ return -ENOMEM;
}
-
irq_ptr->input_qs[i]=q;
}
- for (i=0;i<no_output_qs;i++) {
- q = kzalloc(sizeof(struct qdio_q), GFP_KERNEL);
-
- if (!q) {
- goto out;
- }
+ for (i = 0; i < no_output_qs; i++) {
+ q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
+ if (!q)
+ return -ENOMEM;
+ memset(q, 0, sizeof(*q));
- q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
+ q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
if (!q->slib) {
- QDIO_PRINT_ERR("kmalloc of slib failed!\n");
- goto out;
+ kmem_cache_free(qdio_q_cache, q);
+ return -ENOMEM;
}
-
irq_ptr->output_qs[i]=q;
}
-
- result=0;
-out:
- return result;
+ return 0;
}
static void
QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
if (!irq_ptr) {
- QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n");
+ QDIO_PRINT_ERR("allocation of irq_ptr failed!\n");
return -ENOMEM;
}
init_MUTEX(&irq_ptr->setting_up_sema);
/* QDR must be in DMA area since CCW data address is only 32 bit */
- irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA);
+ irq_ptr->qdr = (struct qdr *) __get_free_page(GFP_KERNEL | GFP_DMA);
if (!(irq_ptr->qdr)) {
free_page((unsigned long) irq_ptr);
- QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n");
+ QDIO_PRINT_ERR("allocation of irq_ptr->qdr failed!\n");
return -ENOMEM;
}
QDIO_DBF_TEXT0(0,setup,"qdr:");
if (qdio_alloc_qs(irq_ptr,
init_data->no_input_qs,
init_data->no_output_qs)) {
+ QDIO_PRINT_ERR("queue allocation failed!\n");
qdio_release_irq_memory(irq_ptr);
return -ENOMEM;
}
if (res)
return res;
+ qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q),
+ 256, 0, NULL);
+ if (!qdio_q_cache) {
+ qdio_release_qdio_memory();
+ return -ENOMEM;
+ }
+
res = qdio_register_dbf_views();
- if (res)
+ if (res) {
+ kmem_cache_destroy(qdio_q_cache);
+ qdio_release_qdio_memory();
return res;
+ }
QDIO_DBF_TEXT0(0,setup,"initQDIO");
res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
qdio_release_qdio_memory();
qdio_unregister_dbf_views();
mempool_destroy(qdio_mempool_scssc);
+ kmem_cache_destroy(qdio_q_cache);
bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
printk("qdio: %s: module removed\n",version);
}