diff options
author | Dave Jones <davej@redhat.com> | 2006-10-03 04:14:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-03 11:04:10 -0400 |
commit | e299dd4d7c5f38a24045e0578049d872b62f21eb (patch) | |
tree | d8ab3a71e434a9137feb4aeddf5c59f58c8ae591 /drivers/video | |
parent | 7a45093b7caa9d3d5421274b4ba80fba5da17e19 (diff) |
[PATCH] fbcon: Use persistent allocation for cursor blinking
Every time the console cursor blinks, we do a kmalloc/kfree pair. This
patch turns that into a single allocation.
This allocation was the most frequent kmalloc I saw on my test box.
[adaplas]
Per Alan's suggestion, move global variables to fbcon's private structure.
This would also avoid resource leaks when fbcon is unloaded.
Signed-off-by: Dave Jones <davej@redhat.com>
Acked-by: Alan Cox <alan@redhat.com>
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/console/fbcon.c | 3 | ||||
-rw-r--r-- | drivers/video/console/fbcon.h | 2 | ||||
-rw-r--r-- | drivers/video/console/softcursor.c | 31 |
3 files changed, 26 insertions, 10 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 1b4f75d1f8a9..050856e09e87 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -3225,7 +3225,10 @@ static void fbcon_exit(void) | |||
3225 | module_put(info->fbops->owner); | 3225 | module_put(info->fbops->owner); |
3226 | 3226 | ||
3227 | if (info->fbcon_par) { | 3227 | if (info->fbcon_par) { |
3228 | struct fbcon_ops *ops = info->fbcon_par; | ||
3229 | |||
3228 | fbcon_del_cursor_timer(info); | 3230 | fbcon_del_cursor_timer(info); |
3231 | kfree(ops->cursor_src); | ||
3229 | kfree(info->fbcon_par); | 3232 | kfree(info->fbcon_par); |
3230 | info->fbcon_par = NULL; | 3233 | info->fbcon_par = NULL; |
3231 | } | 3234 | } |
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index f244ad066d68..b9386d168c04 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h | |||
@@ -80,6 +80,8 @@ struct fbcon_ops { | |||
80 | char *cursor_data; | 80 | char *cursor_data; |
81 | u8 *fontbuffer; | 81 | u8 *fontbuffer; |
82 | u8 *fontdata; | 82 | u8 *fontdata; |
83 | u8 *cursor_src; | ||
84 | u32 cursor_size; | ||
83 | u32 fd_size; | 85 | u32 fd_size; |
84 | }; | 86 | }; |
85 | /* | 87 | /* |
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 557c563e4aed..7d07d8383569 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c | |||
@@ -20,11 +20,12 @@ | |||
20 | 20 | ||
21 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) | 21 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) |
22 | { | 22 | { |
23 | struct fbcon_ops *ops = info->fbcon_par; | ||
23 | unsigned int scan_align = info->pixmap.scan_align - 1; | 24 | unsigned int scan_align = info->pixmap.scan_align - 1; |
24 | unsigned int buf_align = info->pixmap.buf_align - 1; | 25 | unsigned int buf_align = info->pixmap.buf_align - 1; |
25 | unsigned int i, size, dsize, s_pitch, d_pitch; | 26 | unsigned int i, size, dsize, s_pitch, d_pitch; |
26 | struct fb_image *image; | 27 | struct fb_image *image; |
27 | u8 *dst, *src; | 28 | u8 *dst; |
28 | 29 | ||
29 | if (info->state != FBINFO_STATE_RUNNING) | 30 | if (info->state != FBINFO_STATE_RUNNING) |
30 | return 0; | 31 | return 0; |
@@ -32,11 +33,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
32 | s_pitch = (cursor->image.width + 7) >> 3; | 33 | s_pitch = (cursor->image.width + 7) >> 3; |
33 | dsize = s_pitch * cursor->image.height; | 34 | dsize = s_pitch * cursor->image.height; |
34 | 35 | ||
35 | src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC); | 36 | if (dsize + sizeof(struct fb_image) != ops->cursor_size) { |
36 | if (!src) | 37 | if (ops->cursor_src != NULL) |
37 | return -ENOMEM; | 38 | kfree(ops->cursor_src); |
39 | ops->cursor_size = dsize + sizeof(struct fb_image); | ||
38 | 40 | ||
39 | image = (struct fb_image *) (src + dsize); | 41 | ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); |
42 | if (!ops->cursor_src) { | ||
43 | ops->cursor_size = 0; | ||
44 | return -ENOMEM; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | image = (struct fb_image *) (ops->cursor_src + dsize); | ||
40 | *image = cursor->image; | 49 | *image = cursor->image; |
41 | d_pitch = (s_pitch + scan_align) & ~scan_align; | 50 | d_pitch = (s_pitch + scan_align) & ~scan_align; |
42 | 51 | ||
@@ -48,21 +57,23 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
48 | switch (cursor->rop) { | 57 | switch (cursor->rop) { |
49 | case ROP_XOR: | 58 | case ROP_XOR: |
50 | for (i = 0; i < dsize; i++) | 59 | for (i = 0; i < dsize; i++) |
51 | src[i] = image->data[i] ^ cursor->mask[i]; | 60 | ops->cursor_src[i] = image->data[i] ^ |
61 | cursor->mask[i]; | ||
52 | break; | 62 | break; |
53 | case ROP_COPY: | 63 | case ROP_COPY: |
54 | default: | 64 | default: |
55 | for (i = 0; i < dsize; i++) | 65 | for (i = 0; i < dsize; i++) |
56 | src[i] = image->data[i] & cursor->mask[i]; | 66 | ops->cursor_src[i] = image->data[i] & |
67 | cursor->mask[i]; | ||
57 | break; | 68 | break; |
58 | } | 69 | } |
59 | } else | 70 | } else |
60 | memcpy(src, image->data, dsize); | 71 | memcpy(ops->cursor_src, image->data, dsize); |
61 | 72 | ||
62 | fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); | 73 | fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch, |
74 | image->height); | ||
63 | image->data = dst; | 75 | image->data = dst; |
64 | info->fbops->fb_imageblit(info, image); | 76 | info->fbops->fb_imageblit(info, image); |
65 | kfree(src); | ||
66 | return 0; | 77 | return 0; |
67 | } | 78 | } |
68 | 79 | ||