Hello, via_setInit forgot to check drm_alloc's return value, hence caused an oops.
As I thought that via_init_context doesn't check via_setInit's return value, I
changed it a bit. The original code looks a bit confusing, so took a while to
see that it did check the return values. With my changes it finds the last
free index, if the first one is preferred then let the for loop go from
MAX_CONTEXT-1 till zero instead. Mind that the original version didn't free
sets[0] when the second via_setInit failed (not that it would ever come that
far). Feel free to ignore the second patch.
What bothers me is that the kmalloc failed at all. The system wasn't under
heavy memory load, and all I tried running was glxinfo. The uptime wasn't
tremendous either, so memory fragmentation seems unlikely. When looking at the
kernel log there seems to be plenty of usable memory. What's also slightly
worrisome is that the rest of the logfile before the "X: page allocation
failure" is gone. Maybe something more is going on?
All this with 2.6.18-rc1, never happened before.
Greetings,
Indan
(Not subscribed, please CC me)
diff -r a506ed503df2 drivers/char/drm/via_ds.c
--- a/drivers/char/drm/via_ds.c Thu Jul 06 05:03:09 2006 +0000
+++ b/drivers/char/drm/via_ds.c Sun Jul 09 01:28:35 2006 +0200
@@ -31,7 +31,9 @@ set_t *via_setInit(void)
{
int i;
set_t *set;
- set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
+ set = drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
+ if (!set)
+ return NULL;
for (i = 0; i < SET_SIZE; i++) {
set->list[i].free_next = i + 1;
set->list[i].alloc_next = -1;
diff -r a506ed503df2 drivers/char/drm/via_mm.c
--- a/drivers/char/drm/via_mm.c Thu Jul 06 05:03:09 2006 +0000
+++ b/drivers/char/drm/via_mm.c Sun Jul 09 02:01:09 2006 +0200
@@ -107,31 +107,35 @@ int via_init_context(struct drm_device *
int via_init_context(struct drm_device *dev, int context)
{
int i;
-
- for (i = 0; i < MAX_CONTEXT; i++)
- if (global_ppriv[i].used &&
- (global_ppriv[i].context == context))
- break;
-
- if (i >= MAX_CONTEXT) {
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (!global_ppriv[i].used) {
- global_ppriv[i].context = context;
- global_ppriv[i].used = 1;
- global_ppriv[i].sets[0] = via_setInit();
- global_ppriv[i].sets[1] = via_setInit();
- DRM_DEBUG("init allocation set, socket=%d,"
- " context = %d\n", i, context);
- break;
- }
- }
-
- if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
- (global_ppriv[i].sets[1] == NULL)) {
- return 0;
- }
- }
-
+ int idx = -1;
+ set_t *set0;
+ set_t *set1;
+
+ for (i = 0; i < MAX_CONTEXT; i++){
+ if (global_ppriv[i].used){
+ if (global_ppriv[i].context == context)
+ return 1;
+ } else {
+ idx = i;
+ }
+ }
+ if (idx == -1)
+ return 0;
+
+ global_ppriv[idx].context = context;
+ global_ppriv[idx].used = 1;
+ set0 = via_setInit();
+ if (!set0)
+ return 0;
+ set1 = via_setInit();
+ if (!set1){
+ via_setDestroy(set0);
+ return 0;
+ }
+ global_ppriv[idx].sets[0] = set0;
+ global_ppriv[idx].sets[1] = set1;
+ DRM_DEBUG("init allocation set, socket=%d,"
+ " context = %d\n", idx, context);
return 1;
}
kernel.log
Description: Binary data
------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
-- _______________________________________________ Dri-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/dri-devel
