aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2010-01-17 06:56:05 -0500
committerFrederic Weisbecker <fweisbec@gmail.com>2010-01-17 07:11:05 -0500
commit329c0e012b99fa2325a0be205c052e4aba690f16 (patch)
tree07a0ae5bf264c622525d315d87b95ad5f6a22044 /kernel
parent7defb0f879bbcfe29e3c6f29d685d4f29b7a0700 (diff)
perf: Better order flexible and pinned scheduling
When a task gets scheduled in. We don't touch the cpu bound events so the priority order becomes: cpu pinned, cpu flexible, task pinned, task flexible. So schedule out cpu flexibles when a new task context gets in and correctly order the groups to schedule in: task pinned, cpu flexible, task flexible. Cpu pinned groups don't need to be touched at this time. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/perf_event.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index a90ae694cbc1..edc46b92b508 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1362,6 +1362,14 @@ ctx_sched_in(struct perf_event_context *ctx,
1362 raw_spin_unlock(&ctx->lock); 1362 raw_spin_unlock(&ctx->lock);
1363} 1363}
1364 1364
1365static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx,
1366 enum event_type_t event_type)
1367{
1368 struct perf_event_context *ctx = &cpuctx->ctx;
1369
1370 ctx_sched_in(ctx, cpuctx, event_type);
1371}
1372
1365static void task_ctx_sched_in(struct task_struct *task, 1373static void task_ctx_sched_in(struct task_struct *task,
1366 enum event_type_t event_type) 1374 enum event_type_t event_type)
1367{ 1375{
@@ -1388,15 +1396,27 @@ static void task_ctx_sched_in(struct task_struct *task,
1388 */ 1396 */
1389void perf_event_task_sched_in(struct task_struct *task) 1397void perf_event_task_sched_in(struct task_struct *task)
1390{ 1398{
1391 task_ctx_sched_in(task, EVENT_ALL); 1399 struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
1392} 1400 struct perf_event_context *ctx = task->perf_event_ctxp;
1393 1401
1394static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, 1402 if (likely(!ctx))
1395 enum event_type_t event_type) 1403 return;
1396{
1397 struct perf_event_context *ctx = &cpuctx->ctx;
1398 1404
1399 ctx_sched_in(ctx, cpuctx, event_type); 1405 if (cpuctx->task_ctx == ctx)
1406 return;
1407
1408 /*
1409 * We want to keep the following priority order:
1410 * cpu pinned (that don't need to move), task pinned,
1411 * cpu flexible, task flexible.
1412 */
1413 cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
1414
1415 ctx_sched_in(ctx, cpuctx, EVENT_PINNED);
1416 cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE);
1417 ctx_sched_in(ctx, cpuctx, EVENT_FLEXIBLE);
1418
1419 cpuctx->task_ctx = ctx;
1400} 1420}
1401 1421
1402#define MAX_INTERRUPTS (~0ULL) 1422#define MAX_INTERRUPTS (~0ULL)
ass="hl opt">= sp->width; var->yres = sp->height; var->xres_virtual = var->xres; var->yres_virtual = var->yres; var->bits_per_pixel = sp->depth; var->red.offset = 8; var->red.length = 8; var->green.offset = 16; var->green.length = 8; var->blue.offset = 24; var->blue.length = 8; var->transp.offset = 0; var->transp.length = 0; if (fb_alloc_cmap(&info->cmap, 256, 0)) { printk(KERN_ERR "s3d: Cannot allocate color map.\n"); return -ENOMEM; } return 0; } static int __devinit s3d_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) { struct fb_info *info; struct s3d_info *sp; int err; err = pci_enable_device(pdev); if (err < 0) { printk(KERN_ERR "s3d: Cannot enable PCI device %s\n", pci_name(pdev)); goto err_out; } info = framebuffer_alloc(sizeof(struct s3d_info), &pdev->dev); if (!info) { printk(KERN_ERR "s3d: Cannot allocate fb_info\n"); err = -ENOMEM; goto err_disable; } sp = info->par; sp->info = info; sp->pdev = pdev; sp->of_node = pci_device_to_OF_node(pdev); if (!sp->of_node) { printk(KERN_ERR "s3d: Cannot find OF node of %s\n", pci_name(pdev)); err = -ENODEV; goto err_release_fb; } sp->fb_base_phys = pci_resource_start (pdev, 1); err = pci_request_region(pdev, 1, "s3d framebuffer"); if (err < 0) { printk("s3d: Cannot request region 1 for %s\n", pci_name(pdev)); goto err_release_fb; } err = s3d_get_props(sp); if (err) goto err_release_pci; /* XXX 'linebytes' is often wrong, it is equal to the width * XXX with depth of 32 on my XVR-2500 which is clearly not * XXX right. So we don't try to use it. */ switch (sp->depth) { case 8: info->fix.line_length = sp->width; break; case 16: info->fix.line_length = sp->width * 2; break; case 24: info->fix.line_length = sp->width * 3; break; case 32: info->fix.line_length = sp->width * 4; break; } sp->fb_size = info->fix.line_length * sp->height; sp->fb_base = ioremap(sp->fb_base_phys, sp->fb_size); if (!sp->fb_base) goto err_release_pci; err = s3d_set_fbinfo(sp); if (err) goto err_unmap_fb; pci_set_drvdata(pdev, info); printk("s3d: Found device at %s\n", pci_name(pdev)); err = register_framebuffer(info); if (err < 0) { printk(KERN_ERR "s3d: Could not register framebuffer %s\n", pci_name(pdev)); goto err_unmap_fb; } return 0; err_unmap_fb: iounmap(sp->fb_base); err_release_pci: pci_release_region(pdev, 1); err_release_fb: framebuffer_release(info); err_disable: pci_disable_device(pdev); err_out: return err; } static void __devexit s3d_pci_unregister(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); struct s3d_info *sp = info->par; unregister_framebuffer(info); iounmap(sp->fb_base); pci_release_region(pdev, 1); framebuffer_release(info); pci_disable_device(pdev); } static struct pci_device_id s3d_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002c), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002d), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002e), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002f), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0030), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0031), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0032), }, { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0033), }, { 0, } }; static struct pci_driver s3d_driver = { .name = "s3d", .id_table = s3d_pci_table, .probe = s3d_pci_register, .remove = __devexit_p(s3d_pci_unregister), }; static int __init s3d_init(void) { if (fb_get_options("s3d", NULL)) return -ENODEV; return pci_register_driver(&s3d_driver); } static void __exit s3d_exit(void) { pci_unregister_driver(&s3d_driver); } module_init(s3d_init); module_exit(s3d_exit); MODULE_DESCRIPTION("framebuffer driver for Sun XVR-2500 graphics"); MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); MODULE_VERSION("1.0"); MODULE_LICENSE("GPL");