Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Aug 2009 17:41:36 +0000 (10:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Aug 2009 17:41:36 +0000 (10:41 -0700)
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/radeon/kms: setup MC/VRAM the same way for suspend/resume
  drm/radeon/kms: Fix caching mode selection for GTT object

20 files changed:
drivers/mmc/host/sdhci-of.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon_rotate.h
drivers/video/mx3fb.c
drivers/video/via/hw.c
drivers/video/via/lcd.c
drivers/video/via/viafbdev.c
drivers/video/via/viafbdev.h
drivers/w1/masters/omap_hdq.c
fs/binfmt_flat.c
fs/compat_ioctl.c
fs/namespace.c
include/linux/decompress/generic.h
include/linux/nodemask.h
kernel/fork.c
kernel/smp.c
lib/decompress_bunzip2.c
lib/decompress_inflate.c
lib/decompress_unlzma.c
mm/mempolicy.c

index 9088443..1e8aa59 100644 (file)
@@ -234,7 +234,7 @@ static int __devinit sdhci_of_probe(struct of_device *ofdev,
                return -ENODEV;
 
        host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
-       if (!host)
+       if (IS_ERR(host))
                return -ENOMEM;
 
        of_host = sdhci_priv(host);
index 471a9a6..3a44695 100644 (file)
@@ -1082,7 +1082,6 @@ static void fbcon_init(struct vc_data *vc, int init)
        new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
        new_cols /= vc->vc_font.width;
        new_rows /= vc->vc_font.height;
-       vc_resize(vc, new_cols, new_rows);
 
        /*
         * We must always set the mode. The mode of the previous console
@@ -1111,10 +1110,11 @@ static void fbcon_init(struct vc_data *vc, int init)
         *  vc_{cols,rows}, but we must not set those if we are only
         *  resizing the console.
         */
-       if (!init) {
+       if (init) {
                vc->vc_cols = new_cols;
                vc->vc_rows = new_rows;
-       }
+       } else
+               vc_resize(vc, new_cols, new_rows);
 
        if (logo)
                fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
index 75be5ce..e233444 100644 (file)
@@ -45,7 +45,7 @@ static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
        width = (width + 7) & ~7;
 
        for (i = 0; i < height; i++) {
-               for (j = 0; j < width; j++) {
+               for (j = 0; j < width - shift; j++) {
                        if (pattern_test_bit(j, i, width, in))
                                pattern_set_bit(width - (1 + j + shift),
                                                height - (1 + i),
index f8778cd..054ef29 100644 (file)
@@ -669,7 +669,8 @@ static uint32_t bpp_to_pixfmt(int bpp)
 }
 
 static int mx3fb_blank(int blank, struct fb_info *fbi);
-static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len);
+static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,
+                                 bool lock);
 static int mx3fb_unmap_video_memory(struct fb_info *fbi);
 
 /**
@@ -711,12 +712,7 @@ static void mx3fb_dma_done(void *arg)
        complete(&mx3_fbi->flip_cmpl);
 }
 
-/**
- * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
- * @fbi:       framebuffer information pointer.
- * @return:    0 on success or negative error code on failure.
- */
-static int mx3fb_set_par(struct fb_info *fbi)
+static int __set_par(struct fb_info *fbi, bool lock)
 {
        u32 mem_len;
        struct ipu_di_signal_cfg sig_cfg;
@@ -727,10 +723,6 @@ static int mx3fb_set_par(struct fb_info *fbi)
        struct idmac_video_param *video = &ichan->params.video;
        struct scatterlist *sg = mx3_fbi->sg;
 
-       dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');
-
-       mutex_lock(&mx3_fbi->mutex);
-
        /* Total cleanup */
        if (mx3_fbi->txd)
                sdc_disable_channel(mx3_fbi);
@@ -742,10 +734,8 @@ static int mx3fb_set_par(struct fb_info *fbi)
                if (fbi->fix.smem_start)
                        mx3fb_unmap_video_memory(fbi);
 
-               if (mx3fb_map_video_memory(fbi, mem_len) < 0) {
-                       mutex_unlock(&mx3_fbi->mutex);
+               if (mx3fb_map_video_memory(fbi, mem_len, lock) < 0)
                        return -ENOMEM;
-               }
        }
 
        sg_init_table(&sg[0], 1);
@@ -791,7 +781,6 @@ static int mx3fb_set_par(struct fb_info *fbi)
                                   fbi->var.vsync_len,
                                   fbi->var.lower_margin +
                                   fbi->var.vsync_len, sig_cfg) != 0) {
-                       mutex_unlock(&mx3_fbi->mutex);
                        dev_err(fbi->device,
                                "mx3fb: Error initializing panel.\n");
                        return -EINVAL;
@@ -810,9 +799,30 @@ static int mx3fb_set_par(struct fb_info *fbi)
        if (mx3_fbi->blank == FB_BLANK_UNBLANK)
                sdc_enable_channel(mx3_fbi);
 
+       return 0;
+}
+
+/**
+ * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
+ * @fbi:       framebuffer information pointer.
+ * @return:    0 on success or negative error code on failure.
+ */
+static int mx3fb_set_par(struct fb_info *fbi)
+{
+       struct mx3fb_info *mx3_fbi = fbi->par;
+       struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+       struct idmac_channel *ichan = mx3_fbi->idmac_channel;
+       int ret;
+
+       dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');
+
+       mutex_lock(&mx3_fbi->mutex);
+
+       ret = __set_par(fbi, true);
+
        mutex_unlock(&mx3_fbi->mutex);
 
-       return 0;
+       return ret;
 }
 
 /**
@@ -966,21 +976,11 @@ static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
        return ret;
 }
 
-/**
- * mx3fb_blank() - blank the display.
- */
-static int mx3fb_blank(int blank, struct fb_info *fbi)
+static void __blank(int blank, struct fb_info *fbi)
 {
        struct mx3fb_info *mx3_fbi = fbi->par;
        struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
 
-       dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__,
-               blank, fbi->screen_base, fbi->fix.smem_len);
-
-       if (mx3_fbi->blank == blank)
-               return 0;
-
-       mutex_lock(&mx3_fbi->mutex);
        mx3_fbi->blank = blank;
 
        switch (blank) {
@@ -999,6 +999,23 @@ static int mx3fb_blank(int blank, struct fb_info *fbi)
                sdc_set_brightness(mx3fb, mx3fb->backlight_level);
                break;
        }
+}
+
+/**
+ * mx3fb_blank() - blank the display.
+ */
+static int mx3fb_blank(int blank, struct fb_info *fbi)
+{
+       struct mx3fb_info *mx3_fbi = fbi->par;
+
+       dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__,
+               blank, fbi->screen_base, fbi->fix.smem_len);
+
+       if (mx3_fbi->blank == blank)
+               return 0;
+
+       mutex_lock(&mx3_fbi->mutex);
+       __blank(blank, fbi);
        mutex_unlock(&mx3_fbi->mutex);
 
        return 0;
@@ -1198,6 +1215,7 @@ static int mx3fb_resume(struct platform_device *pdev)
  * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
  * @fbi:       framebuffer information pointer
  * @mem_len:   length of mapped memory
+ * @lock:      do not lock during initialisation
  * @return:    Error code indicating success or failure
  *
  * This buffer is remapped into a non-cached, non-buffered, memory region to
@@ -1205,7 +1223,8 @@ static int mx3fb_resume(struct platform_device *pdev)
  * area is remapped, all virtual memory access to the video memory should occur
  * at the new region.
  */
-static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len)
+static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,
+                                 bool lock)
 {
        int retval = 0;
        dma_addr_t addr;
@@ -1221,10 +1240,12 @@ static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len)
                goto err0;
        }
 
-       mutex_lock(&fbi->mm_lock);
+       if (lock)
+               mutex_lock(&fbi->mm_lock);
        fbi->fix.smem_start = addr;
        fbi->fix.smem_len = mem_len;
-       mutex_unlock(&fbi->mm_lock);
+       if (lock)
+               mutex_unlock(&fbi->mm_lock);
 
        dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",
                (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
@@ -1365,6 +1386,11 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
        init_completion(&mx3fbi->flip_cmpl);
        disable_irq(ichan->eof_irq);
        dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
+       ret = __set_par(fbi, false);
+       if (ret < 0)
+               goto esetpar;
+
+       __blank(FB_BLANK_UNBLANK, fbi);
 
        dev_info(dev, "registered, using mode %s\n", fb_mode);
 
index fcd53ce..c896000 100644 (file)
@@ -2407,14 +2407,14 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
                        viafb_dvi_set_mode(viafb_get_mode_index
                                     (viaparinfo->tmds_setting_info->h_active,
                                      viaparinfo->tmds_setting_info->
-                                     v_active, 1),
+                                     v_active),
                                     video_bpp1, viaparinfo->
                                     tmds_setting_info->iga_path);
                } else {
                        viafb_dvi_set_mode(viafb_get_mode_index
                                     (viaparinfo->tmds_setting_info->h_active,
                                      viaparinfo->
-                                     tmds_setting_info->v_active, 0),
+                                     tmds_setting_info->v_active),
                                     video_bpp, viaparinfo->
                                     tmds_setting_info->iga_path);
                }
index 6c7290a..78c6b33 100644 (file)
@@ -580,10 +580,7 @@ static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
        int reg_num = 0;
        struct io_reg *lcd_patch_reg = NULL;
 
-       if (viaparinfo->lvds_setting_info->iga_path == IGA2)
-               vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
-       else
-               vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+       vmode_index = viafb_get_mode_index(set_hres, set_vres);
        switch (panel_id) {
                /* LCD 800x600 */
        case LCD_PANEL_ID1_800X600:
@@ -761,10 +758,7 @@ static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
        int reg_num = 0;
        struct io_reg *lcd_patch_reg = NULL;
 
-       if (viaparinfo->lvds_setting_info->iga_path == IGA2)
-               vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
-       else
-               vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+       vmode_index = viafb_get_mode_index(set_hres, set_vres);
 
        switch (panel_id) {
        case LCD_PANEL_ID5_1400X1050:
@@ -832,10 +826,7 @@ static void load_lcd_patch_regs(int set_hres, int set_vres,
 {
        int vmode_index;
 
-       if (viaparinfo->lvds_setting_info->iga_path == IGA2)
-               vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
-       else
-               vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+       vmode_index = viafb_get_mode_index(set_hres, set_vres);
 
        viafb_unlock_crt();
 
index a0fec29..72833f3 100644 (file)
@@ -32,7 +32,6 @@ static u32 pseudo_pal[17];
 /* video mode */
 static char *viafb_mode = "640x480";
 static char *viafb_mode1 = "640x480";
-static int viafb_resMode = VIA_RES_640X480;
 
 /* Added for specifying active devices.*/
 char *viafb_active_dev = "";
@@ -56,47 +55,47 @@ static void viafb_get_video_device(u32 *video_dev_info);
 
 /* Mode information */
 static const struct viafb_modeinfo viafb_modentry[] = {
-       {480, 640, VIA_RES_480X640, "480x640"},
-       {640, 480, VIA_RES_640X480, "640x480"},
-       {800, 480, VIA_RES_800X480, "800x480"},
-       {800, 600, VIA_RES_800X600, "800x600"},
-       {1024, 768, VIA_RES_1024X768, "1024x768"},
-       {1152, 864, VIA_RES_1152X864, "1152x864"},
-       {1280, 1024, VIA_RES_1280X1024, "1280x1024"},
-       {1600, 1200, VIA_RES_1600X1200, "1600x1200"},
-       {1440, 1050, VIA_RES_1440X1050, "1440x1050"},
-       {1280, 768, VIA_RES_1280X768, "1280x768"},
-       {1280, 800, VIA_RES_1280X800, "1280x800"},
-       {1280, 960, VIA_RES_1280X960, "1280x960"},
-       {1920, 1440, VIA_RES_1920X1440, "1920x1440"},
-       {848, 480, VIA_RES_848X480, "848x480"},
-       {1400, 1050, VIA_RES_1400X1050, "1400x1050"},
-       {720, 480, VIA_RES_720X480, "720x480"},
-       {720, 576, VIA_RES_720X576, "720x576"},
-       {1024, 512, VIA_RES_1024X512, "1024x512"},
-       {1024, 576, VIA_RES_1024X576, "1024x576"},
-       {1024, 600, VIA_RES_1024X600, "1024x600"},
-       {1280, 720, VIA_RES_1280X720, "1280x720"},
-       {1920, 1080, VIA_RES_1920X1080, "1920x1080"},
-       {1366, 768, VIA_RES_1368X768, "1368x768"},
-       {1680, 1050, VIA_RES_1680X1050, "1680x1050"},
-       {960, 600, VIA_RES_960X600, "960x600"},
-       {1000, 600, VIA_RES_1000X600, "1000x600"},
-       {1024, 576, VIA_RES_1024X576, "1024x576"},
-       {1024, 600, VIA_RES_1024X600, "1024x600"},
-       {1088, 612, VIA_RES_1088X612, "1088x612"},
-       {1152, 720, VIA_RES_1152X720, "1152x720"},
-       {1200, 720, VIA_RES_1200X720, "1200x720"},
-       {1280, 600, VIA_RES_1280X600, "1280x600"},
-       {1360, 768, VIA_RES_1360X768, "1360x768"},
-       {1440, 900, VIA_RES_1440X900, "1440x900"},
-       {1600, 900, VIA_RES_1600X900, "1600x900"},
-       {1600, 1024, VIA_RES_1600X1024, "1600x1024"},
-       {1792, 1344, VIA_RES_1792X1344, "1792x1344"},
-       {1856, 1392, VIA_RES_1856X1392, "1856x1392"},
-       {1920, 1200, VIA_RES_1920X1200, "1920x1200"},
-       {2048, 1536, VIA_RES_2048X1536, "2048x1536"},
-       {0, 0, VIA_RES_INVALID, "640x480"}
+       {480, 640, VIA_RES_480X640},
+       {640, 480, VIA_RES_640X480},
+       {800, 480, VIA_RES_800X480},
+       {800, 600, VIA_RES_800X600},
+       {1024, 768, VIA_RES_1024X768},
+       {1152, 864, VIA_RES_1152X864},
+       {1280, 1024, VIA_RES_1280X1024},
+       {1600, 1200, VIA_RES_1600X1200},
+       {1440, 1050, VIA_RES_1440X1050},
+       {1280, 768, VIA_RES_1280X768,},
+       {1280, 800, VIA_RES_1280X800},
+       {1280, 960, VIA_RES_1280X960},
+       {1920, 1440, VIA_RES_1920X1440},
+       {848, 480, VIA_RES_848X480},
+       {1400, 1050, VIA_RES_1400X1050},
+       {720, 480, VIA_RES_720X480},
+       {720, 576, VIA_RES_720X576},
+       {1024, 512, VIA_RES_1024X512},
+       {1024, 576, VIA_RES_1024X576},
+       {1024, 600, VIA_RES_1024X600},
+       {1280, 720, VIA_RES_1280X720},
+       {1920, 1080, VIA_RES_1920X1080},
+       {1366, 768, VIA_RES_1368X768},
+       {1680, 1050, VIA_RES_1680X1050},
+       {960, 600, VIA_RES_960X600},
+       {1000, 600, VIA_RES_1000X600},
+       {1024, 576, VIA_RES_1024X576},
+       {1024, 600, VIA_RES_1024X600},
+       {1088, 612, VIA_RES_1088X612},
+       {1152, 720, VIA_RES_1152X720},
+       {1200, 720, VIA_RES_1200X720},
+       {1280, 600, VIA_RES_1280X600},
+       {1360, 768, VIA_RES_1360X768},
+       {1440, 900, VIA_RES_1440X900},
+       {1600, 900, VIA_RES_1600X900},
+       {1600, 1024, VIA_RES_1600X1024},
+       {1792, 1344, VIA_RES_1792X1344},
+       {1856, 1392, VIA_RES_1856X1392},
+       {1920, 1200, VIA_RES_1920X1200},
+       {2048, 1536, VIA_RES_2048X1536},
+       {0, 0, VIA_RES_INVALID}
 };
 
 static struct fb_ops viafb_ops;
@@ -177,7 +176,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
        if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
                return -EINVAL;
 
-       vmode_index = viafb_get_mode_index(var->xres, var->yres, 0);
+       vmode_index = viafb_get_mode_index(var->xres, var->yres);
        if (vmode_index == VIA_RES_INVALID) {
                DEBUG_MSG(KERN_INFO
                          "viafb: Mode %dx%dx%d not supported!!\n",
@@ -233,14 +232,14 @@ static int viafb_set_par(struct fb_info *info)
        viafb_update_device_setting(info->var.xres, info->var.yres,
                              info->var.bits_per_pixel, viafb_refresh, 0);
 
-       vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres, 0);
+       vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres);
 
        if (viafb_SAMM_ON == 1) {
                DEBUG_MSG(KERN_INFO
                "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
                          viafb_second_xres, viafb_second_yres, viafb_bpp1);
                vmode_index1 = viafb_get_mode_index(viafb_second_xres,
-                       viafb_second_yres, 1);
+                       viafb_second_yres);
                DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n",
                        vmode_index1);
 
@@ -1262,7 +1261,7 @@ static int viafb_sync(struct fb_info *info)
        return 0;
 }
 
-int viafb_get_mode_index(int hres, int vres, int flag)
+int viafb_get_mode_index(int hres, int vres)
 {
        u32 i;
        DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");
@@ -1272,13 +1271,7 @@ int viafb_get_mode_index(int hres, int vres, int flag)
                        viafb_modentry[i].yres == vres)
                        break;
 
-       viafb_resMode = viafb_modentry[i].mode_index;
-       if (flag)
-               viafb_mode1 = viafb_modentry[i].mode_res;
-       else
-               viafb_mode = viafb_modentry[i].mode_res;
-
-       return viafb_resMode;
+       return viafb_modentry[i].mode_index;
 }
 
 static void check_available_device_to_enable(int device_id)
@@ -2199,7 +2192,7 @@ static int __devinit via_pci_probe(void)
        strict_strtoul(tmpc, 0, &default_xres);
        strict_strtoul(tmpm, 0, &default_yres);
 
-       vmode_index = viafb_get_mode_index(default_xres, default_yres, 0);
+       vmode_index = viafb_get_mode_index(default_xres, default_yres);
        DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
 
        if (viafb_SAMM_ON == 1) {
index a4158e8..227b000 100644 (file)
@@ -81,7 +81,6 @@ struct viafb_modeinfo {
        u32 xres;
        u32 yres;
        int mode_index;
-       char *mode_res;
 };
 extern unsigned int viafb_second_virtual_yres;
 extern unsigned int viafb_second_virtual_xres;
@@ -102,7 +101,7 @@ extern int strict_strtoul(const char *cp, unsigned int base,
 void viafb_memory_pitch_patch(struct fb_info *info);
 void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
                          int mode_index);
-int viafb_get_mode_index(int hres, int vres, int flag);
+int viafb_get_mode_index(int hres, int vres);
 u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
        *plvds_setting_info, struct lvds_chip_information
        *plvds_chip_info, u8 index);
index a7e3b70..0d92969 100644 (file)
@@ -687,6 +687,7 @@ static int omap_hdq_remove(struct platform_device *pdev)
 
        if (hdq_data->hdq_usecount) {
                dev_dbg(&pdev->dev, "removed when use count is not zero\n");
+               mutex_unlock(&hdq_data->hdq_mutex);
                return -EBUSY;
        }
 
index 697f6b5..e92f229 100644 (file)
@@ -828,15 +828,22 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
        if (IS_ERR(bprm.file))
                return res;
 
+       bprm.cred = prepare_exec_creds();
+       res = -ENOMEM;
+       if (!bprm.cred)
+               goto out;
+
        res = prepare_binprm(&bprm);
 
        if (res <= (unsigned long)-4096)
                res = load_flat_file(&bprm, libs, id, NULL);
-       if (bprm.file) {
-               allow_write_access(bprm.file);
-               fput(bprm.file);
-               bprm.file = NULL;
-       }
+
+       abort_creds(bprm.cred);
+
+out:
+       allow_write_access(bprm.file);
+       fput(bprm.file);
+
        return(res);
 }
 
index f28f070..f91fd51 100644 (file)
@@ -1905,6 +1905,7 @@ COMPATIBLE_IOCTL(FIONCLEX)
 COMPATIBLE_IOCTL(FIOASYNC)
 COMPATIBLE_IOCTL(FIONBIO)
 COMPATIBLE_IOCTL(FIONREAD)  /* This is also TIOCINQ */
+COMPATIBLE_IOCTL(FS_IOC_FIEMAP)
 /* 0x00 */
 COMPATIBLE_IOCTL(FIBMAP)
 COMPATIBLE_IOCTL(FIGETBSZ)
index 277c28a..7230787 100644 (file)
@@ -316,7 +316,8 @@ EXPORT_SYMBOL_GPL(mnt_clone_write);
  */
 int mnt_want_write_file(struct file *file)
 {
-       if (!(file->f_mode & FMODE_WRITE))
+       struct inode *inode = file->f_dentry->d_inode;
+       if (!(file->f_mode & FMODE_WRITE) || special_file(inode->i_mode))
                return mnt_want_write(file->f_path.mnt);
        else
                return mnt_clone_write(file->f_path.mnt);
index 6dfb856..0c7111a 100644 (file)
@@ -1,31 +1,37 @@
 #ifndef DECOMPRESS_GENERIC_H
 #define DECOMPRESS_GENERIC_H
 
-/* Minimal chunksize to be read.
- *Bzip2 prefers at least 4096
- *Lzma prefers 0x10000 */
-#define COMPR_IOBUF_SIZE       4096
-
 typedef int (*decompress_fn) (unsigned char *inbuf, int len,
                              int(*fill)(void*, unsigned int),
-                             int(*writebb)(void*, unsigned int),
-                             unsigned char *output,
+                             int(*flush)(void*, unsigned int),
+                             unsigned char *outbuf,
                              int *posp,
                              void(*error)(char *x));
 
 /* inbuf   - input buffer
  *len     - len of pre-read data in inbuf
- *fill    - function to fill inbuf if empty
- *writebb - function to write out outbug
+ *fill    - function to fill inbuf when empty
+ *flush   - function to write out outbuf
+ *outbuf  - output buffer
  *posp    - if non-null, input position (number of bytes read) will be
  *       returned here
  *
- *If len != 0, the inbuf is initialized (with as much data), and fill
- *should not be called
- *If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE
- *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE
+ *If len != 0, inbuf should contain all the necessary input data, and fill
+ *should be NULL
+ *If len = 0, inbuf can be NULL, in which case the decompressor will allocate
+ *the input buffer.  If inbuf != NULL it must be at least XXX_IOBUF_SIZE bytes.
+ *fill will be called (repeatedly...) to read data, at most XXX_IOBUF_SIZE
+ *bytes should be read per call.  Replace XXX with the appropriate decompressor
+ *name, i.e. LZMA_IOBUF_SIZE.
+ *
+ *If flush = NULL, outbuf must be large enough to buffer all the expected
+ *output.  If flush != NULL, the output buffer will be allocated by the
+ *decompressor (outbuf = NULL), and the flush function will be called to
+ *flush the output buffer at the appropriate time (decompressor and stream
+ *dependent).
  */
 
+
 /* Utility routine to detect the decompression method */
 decompress_fn decompress_method(const unsigned char *inbuf, int len,
                                const char **name);
index 829b94b..b359c4a 100644 (file)
  *    to generate slightly worse code.  So use a simple one-line #define
  *    for node_isset(), instead of wrapping an inline inside a macro, the
  *    way we do the other calls.
+ *
+ * NODEMASK_SCRATCH
+ * When doing above logical AND, OR, XOR, Remap operations the callers tend to
+ * need temporary nodemask_t's on the stack. But if NODES_SHIFT is large,
+ * nodemask_t's consume too much stack space.  NODEMASK_SCRATCH is a helper
+ * for such situations. See below and CPUMASK_ALLOC also.
  */
 
 #include <linux/kernel.h>
@@ -473,4 +479,26 @@ static inline int num_node_state(enum node_states state)
 #define for_each_node(node)       for_each_node_state(node, N_POSSIBLE)
 #define for_each_online_node(node) for_each_node_state(node, N_ONLINE)
 
+/*
+ * For nodemask scrach area.(See CPUMASK_ALLOC() in cpumask.h)
+ */
+
+#if NODES_SHIFT > 8 /* nodemask_t > 64 bytes */
+#define NODEMASK_ALLOC(x, m) struct x *m = kmalloc(sizeof(*m), GFP_KERNEL)
+#define NODEMASK_FREE(m) kfree(m)
+#else
+#define NODEMASK_ALLOC(x, m) struct x _m, *m = &_m
+#define NODEMASK_FREE(m)
+#endif
+
+/* A example struture for using NODEMASK_ALLOC, used in mempolicy. */
+struct nodemask_scratch {
+       nodemask_t      mask1;
+       nodemask_t      mask2;
+};
+
+#define NODEMASK_SCRATCH(x) NODEMASK_ALLOC(nodemask_scratch, x)
+#define NODEMASK_SCRATCH_FREE(x)  NODEMASK_FREE(x)
+
+
 #endif /* __LINUX_NODEMASK_H */
index 466531e..021e113 100644 (file)
@@ -568,18 +568,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
         * the value intact in a core dump, and to save the unnecessary
         * trouble otherwise.  Userland only wants this done for a sys_exit.
         */
-       if (tsk->clear_child_tid
-           && !(tsk->flags & PF_SIGNALED)
-           && atomic_read(&mm->mm_users) > 1) {
-               u32 __user * tidptr = tsk->clear_child_tid;
+       if (tsk->clear_child_tid) {
+               if (!(tsk->flags & PF_SIGNALED) &&
+                   atomic_read(&mm->mm_users) > 1) {
+                       /*
+                        * We don't check the error code - if userspace has
+                        * not set up a proper pointer then tough luck.
+                        */
+                       put_user(0, tsk->clear_child_tid);
+                       sys_futex(tsk->clear_child_tid, FUTEX_WAKE,
+                                       1, NULL, NULL, 0);
+               }
                tsk->clear_child_tid = NULL;
-
-               /*
-                * We don't check the error code - if userspace has
-                * not set up a proper pointer then tough luck.
-                */
-               put_user(0, tidptr);
-               sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
        }
 }
 
index ad63d85..94188b8 100644 (file)
@@ -57,7 +57,7 @@ hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
                        return NOTIFY_BAD;
                break;
 
-#ifdef CONFIG_CPU_HOTPLUG
+#ifdef CONFIG_HOTPLUG_CPU
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
 
index 708e2a8..600f473 100644 (file)
 */
 
 
-#ifndef STATIC
+#ifdef STATIC
+#define PREBOOT
+#else
 #include <linux/decompress/bunzip2.h>
-#endif /* !STATIC */
+#include <linux/slab.h>
+#endif /* STATIC */
 
 #include <linux/decompress/mm.h>
-#include <linux/slab.h>
 
 #ifndef INT_MAX
 #define INT_MAX 0x7fffffff
@@ -681,9 +683,7 @@ STATIC int INIT bunzip2(unsigned char *buf, int len,
        set_error_fn(error_fn);
        if (flush)
                outbuf = malloc(BZIP2_IOBUF_SIZE);
-       else
-               len -= 4; /* Uncompressed size hack active in pre-boot
-                            environment */
+
        if (!outbuf) {
                error("Could not allocate output bufer");
                return -1;
@@ -733,4 +733,14 @@ exit_0:
        return i;
 }
 
-#define decompress bunzip2
+#ifdef PREBOOT
+STATIC int INIT decompress(unsigned char *buf, int len,
+                       int(*fill)(void*, unsigned int),
+                       int(*flush)(void*, unsigned int),
+                       unsigned char *outbuf,
+                       int *pos,
+                       void(*error_fn)(char *x))
+{
+       return bunzip2(buf, len - 4, fill, flush, outbuf, pos, error_fn);
+}
+#endif
index e36b296..68dfce5 100644 (file)
 #include "zlib_inflate/inflate.h"
 
 #include "zlib_inflate/infutil.h"
+#include <linux/slab.h>
 
 #endif /* STATIC */
 
 #include <linux/decompress/mm.h>
-#include <linux/slab.h>
 
-#define INBUF_LEN (16*1024)
+#define GZIP_IOBUF_SIZE (16*1024)
 
 /* Included from initramfs et al code */
 STATIC int INIT gunzip(unsigned char *buf, int len,
@@ -55,7 +55,7 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
        if (buf)
                zbuf = buf;
        else {
-               zbuf = malloc(INBUF_LEN);
+               zbuf = malloc(GZIP_IOBUF_SIZE);
                len = 0;
        }
        if (!zbuf) {
@@ -77,7 +77,7 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
        }
 
        if (len == 0)
-               len = fill(zbuf, INBUF_LEN);
+               len = fill(zbuf, GZIP_IOBUF_SIZE);
 
        /* verify the gzip header */
        if (len < 10 ||
@@ -113,7 +113,7 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
        while (rc == Z_OK) {
                if (strm->avail_in == 0) {
                        /* TODO: handle case where both pos and fill are set */
-                       len = fill(zbuf, INBUF_LEN);
+                       len = fill(zbuf, GZIP_IOBUF_SIZE);
                        if (len < 0) {
                                rc = -1;
                                error("read error");
index 32123a1..0b954e0 100644 (file)
  *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef STATIC
+#ifdef STATIC
+#define PREBOOT
+#else
 #include <linux/decompress/unlzma.h>
+#include <linux/slab.h>
 #endif /* STATIC */
 
 #include <linux/decompress/mm.h>
-#include <linux/slab.h>
 
 #define        MIN(a, b) (((a) < (b)) ? (a) : (b))
 
@@ -543,9 +545,7 @@ STATIC inline int INIT unlzma(unsigned char *buf, int in_len,
        int ret = -1;
 
        set_error_fn(error_fn);
-       if (!flush)
-               in_len -= 4; /* Uncompressed size hack active in pre-boot
-                               environment */
+
        if (buf)
                inbuf = buf;
        else
@@ -645,4 +645,15 @@ exit_0:
        return ret;
 }
 
-#define decompress unlzma
+#ifdef PREBOOT
+STATIC int INIT decompress(unsigned char *buf, int in_len,
+                             int(*fill)(void*, unsigned int),
+                             int(*flush)(void*, unsigned int),
+                             unsigned char *output,
+                             int *posp,
+                             void(*error_fn)(char *x)
+       )
+{
+       return unlzma(buf, in_len - 4, fill, flush, output, posp, error_fn);
+}
+#endif
index e08e2c4..7dd9d9f 100644 (file)
@@ -191,25 +191,27 @@ static int mpol_new_bind(struct mempolicy *pol, const nodemask_t *nodes)
  * Must be called holding task's alloc_lock to protect task's mems_allowed
  * and mempolicy.  May also be called holding the mmap_semaphore for write.
  */
-static int mpol_set_nodemask(struct mempolicy *pol, const nodemask_t *nodes)
+static int mpol_set_nodemask(struct mempolicy *pol,
+                    const nodemask_t *nodes, struct nodemask_scratch *nsc)
 {
-       nodemask_t cpuset_context_nmask;
        int ret;
 
        /* if mode is MPOL_DEFAULT, pol is NULL. This is right. */
        if (pol == NULL)
                return 0;
+       /* Check N_HIGH_MEMORY */
+       nodes_and(nsc->mask1,
+                 cpuset_current_mems_allowed, node_states[N_HIGH_MEMORY]);
 
        VM_BUG_ON(!nodes);
        if (pol->mode == MPOL_PREFERRED && nodes_empty(*nodes))
                nodes = NULL;   /* explicit local allocation */
        else {
                if (pol->flags & MPOL_F_RELATIVE_NODES)
-                       mpol_relative_nodemask(&cpuset_context_nmask, nodes,
-                                              &cpuset_current_mems_allowed);
+                       mpol_relative_nodemask(&nsc->mask2, nodes,&nsc->mask1);
                else
-                       nodes_and(cpuset_context_nmask, *nodes,
-                                 cpuset_current_mems_allowed);
+                       nodes_and(nsc->mask2, *nodes, nsc->mask1);
+
                if (mpol_store_user_nodemask(pol))
                        pol->w.user_nodemask = *nodes;
                else
@@ -217,8 +219,10 @@ static int mpol_set_nodemask(struct mempolicy *pol, const nodemask_t *nodes)
                                                cpuset_current_mems_allowed;
        }
 
-       ret = mpol_ops[pol->mode].create(pol,
-                               nodes ? &cpuset_context_nmask : NULL);
+       if (nodes)
+               ret = mpol_ops[pol->mode].create(pol, &nsc->mask2);
+       else
+               ret = mpol_ops[pol->mode].create(pol, NULL);
        return ret;
 }
 
@@ -620,12 +624,17 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags,
 {
        struct mempolicy *new, *old;
        struct mm_struct *mm = current->mm;
+       NODEMASK_SCRATCH(scratch);
        int ret;
 
-       new = mpol_new(mode, flags, nodes);
-       if (IS_ERR(new))
-               return PTR_ERR(new);
+       if (!scratch)
+               return -ENOMEM;
 
+       new = mpol_new(mode, flags, nodes);
+       if (IS_ERR(new)) {
+               ret = PTR_ERR(new);
+               goto out;
+       }
        /*
         * prevent changing our mempolicy while show_numa_maps()
         * is using it.
@@ -635,13 +644,13 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags,
        if (mm)
                down_write(&mm->mmap_sem);
        task_lock(current);
-       ret = mpol_set_nodemask(new, nodes);
+       ret = mpol_set_nodemask(new, nodes, scratch);
        if (ret) {
                task_unlock(current);
                if (mm)
                        up_write(&mm->mmap_sem);
                mpol_put(new);
-               return ret;
+               goto out;
        }
        old = current->mempolicy;
        current->mempolicy = new;
@@ -654,7 +663,10 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags,
                up_write(&mm->mmap_sem);
 
        mpol_put(old);
-       return 0;
+       ret = 0;
+out:
+       NODEMASK_SCRATCH_FREE(scratch);
+       return ret;
 }
 
 /*
@@ -1014,12 +1026,20 @@ static long do_mbind(unsigned long start, unsigned long len,
                if (err)
                        return err;
        }
-       down_write(&mm->mmap_sem);
-       task_lock(current);
-       err = mpol_set_nodemask(new, nmask);
-       task_unlock(current);
+       {
+               NODEMASK_SCRATCH(scratch);
+               if (scratch) {
+                       down_write(&mm->mmap_sem);
+                       task_lock(current);
+                       err = mpol_set_nodemask(new, nmask, scratch);
+                       task_unlock(current);
+                       if (err)
+                               up_write(&mm->mmap_sem);
+               } else
+                       err = -ENOMEM;
+               NODEMASK_SCRATCH_FREE(scratch);
+       }
        if (err) {
-               up_write(&mm->mmap_sem);
                mpol_put(new);
                return err;
        }
@@ -1891,6 +1911,7 @@ restart:
  * Install non-NULL @mpol in inode's shared policy rb-tree.
  * On entry, the current task has a reference on a non-NULL @mpol.
  * This must be released on exit.
+ * This is called at get_inode() calls and we can use GFP_KERNEL.
  */
 void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
 {
@@ -1902,19 +1923,24 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
        if (mpol) {
                struct vm_area_struct pvma;
                struct mempolicy *new;
+               NODEMASK_SCRATCH(scratch);
 
+               if (!scratch)
+                       return;
                /* contextualize the tmpfs mount point mempolicy */
                new = mpol_new(mpol->mode, mpol->flags, &mpol->w.user_nodemask);
                if (IS_ERR(new)) {
                        mpol_put(mpol); /* drop our ref on sb mpol */
+                       NODEMASK_SCRATCH_FREE(scratch);
                        return;         /* no valid nodemask intersection */
                }
 
                task_lock(current);
-               ret = mpol_set_nodemask(new, &mpol->w.user_nodemask);
+               ret = mpol_set_nodemask(new, &mpol->w.user_nodemask, scratch);
                task_unlock(current);
                mpol_put(mpol); /* drop our ref on sb mpol */
                if (ret) {
+                       NODEMASK_SCRATCH_FREE(scratch);
                        mpol_put(new);
                        return;
                }
@@ -1924,6 +1950,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
                pvma.vm_end = TASK_SIZE;        /* policy covers entire file */
                mpol_set_shared_policy(sp, &pvma, new); /* adds ref */
                mpol_put(new);                  /* drop initial ref */
+               NODEMASK_SCRATCH_FREE(scratch);
        }
 }
 
@@ -2140,13 +2167,18 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                err = 1;
        else {
                int ret;
-
-               task_lock(current);
-               ret = mpol_set_nodemask(new, &nodes);
-               task_unlock(current);
-               if (ret)
+               NODEMASK_SCRATCH(scratch);
+               if (scratch) {
+                       task_lock(current);
+                       ret = mpol_set_nodemask(new, &nodes, scratch);
+                       task_unlock(current);
+               } else
+                       ret = -ENOMEM;
+               NODEMASK_SCRATCH_FREE(scratch);
+               if (ret) {
                        err = 1;
-               else if (no_context) {
+                       mpol_put(new);
+               } else if (no_context) {
                        /* save for contextualization */
                        new->w.user_nodemask = nodes;
                }