From patchwork Tue Sep 20 07:04:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 672125 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sdYjt11rQz9sC7 for ; Tue, 20 Sep 2016 17:07:46 +1000 (AEST) Received: from localhost ([::1]:60792 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmF9b-00033v-RT for incoming@patchwork.ozlabs.org; Tue, 20 Sep 2016 03:07:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37487) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmF77-0001F5-6N for qemu-devel@nongnu.org; Tue, 20 Sep 2016 03:05:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bmF71-0000AV-4l for qemu-devel@nongnu.org; Tue, 20 Sep 2016 03:05:07 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45766) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bmF70-00009T-TR for qemu-devel@nongnu.org; Tue, 20 Sep 2016 03:05:03 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C80AE8AE6C for ; Tue, 20 Sep 2016 07:05:00 +0000 (UTC) Received: from max-t460s.redhat.com (vpn1-6-157.ams2.redhat.com [10.36.6.157]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8K74xl1000429; Tue, 20 Sep 2016 03:04:59 -0400 From: Maxime Coquelin To: armbru@redhat.com, qemu-devel@nongnu.org Date: Tue, 20 Sep 2016 09:04:56 +0200 Message-Id: <1474355096-28059-1-git-send-email-maxime.coquelin@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 20 Sep 2016 07:05:00 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC] scripts: qmp: Introduce vcpu pinning helper script X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Maxime Coquelin , lcapitulino@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This python script calls 'query-cpus' QMP command to retrieve vCPUs thread IDs. Thread IDs are then used by taskset to pin vCPUs to physical CPUs passed in command line. In case more vCPUs are present than the number of CPUs assigned in command line, multiple vCPUs get pinned to physical CPUs. Signed-off-by: Maxime Coquelin Reviewed-by: Peter Xu Tested-by: Peter Xu --- This script is not for production, where libvirt should be used. However, I find it useful during development, so I propose to share it as it might interest other people. Note: it seems that tcp socket support is broken with QMP class. The bug has already been reported and patch proposed[0]. So it has only been tested with UNIX socket. [0]: scripts/qmp/qmp-vcpu-pin | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100755 scripts/qmp/qmp-vcpu-pin diff --git a/scripts/qmp/qmp-vcpu-pin b/scripts/qmp/qmp-vcpu-pin new file mode 100755 index 0000000..7bf96f7 --- /dev/null +++ b/scripts/qmp/qmp-vcpu-pin @@ -0,0 +1,39 @@ +#!/usr/bin/python +# QEMU vCPU pinning tool +# +# Copyright (C) 2016 Red Hat Inc. +# +# Authors: +# Maxime Coquelin +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory +import argparse +import json +import os + +from subprocess import call +from qmp import QEMUMonitorProtocol + +parser = argparse.ArgumentParser(description='Pin QEMU vCPUs to physical CPUs') +parser.add_argument('-s', '--server', type=str, required=True, + help='QMP server path or address:port') +parser.add_argument('cpu', type=int, nargs='+', + help='Physical CPUs IDs') +args = parser.parse_args() + +devnull = open(os.devnull, 'w') + +srv = QEMUMonitorProtocol(args.server) +srv.connect() + +for vcpu in srv.command('query-cpus'): + vcpuid = vcpu['CPU'] + tid = vcpu['thread_id'] + cpuid = args.cpu[vcpuid % len(args.cpu)] + print 'Pin vCPU {} (tid {}) to physical CPU {}'.format(vcpuid, tid, cpuid) + try: + call(['taskset', '-pc', str(cpuid), str(tid)], stdout=devnull) + except OSError: + print 'Failed to pin vCPU{} to CPU{}'.format(vcpuid, cpuid) +