# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# Deploy this DaemonSet to disable hyper-threading on the nodes with the
# "cloud.google.com/gke-smt-disabled=true" label.
#
# WARNING: Disabling hyper-threading might have severe performance impact on
# your clusters and application. Please ensure that this is acceptable before
# deploying this to your production clusters.
#
# WARNING: Disabling hyper-threading requires node reboot. Therefore, in order
# to avoid disrupting your workloads, it is recommended to create a new node
# pool with the "cloud.google.com/gke-smt-disabled=true" label in your cluster,
# deploy the DaemonSet to disable hyper-threading in that node pool, and then
# migrate your workloads to the new node pool.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: disable-smt
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: disable-smt
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        name: disable-smt
    spec:
      tolerations:
      - operator: Exists
      volumes:
      - name: host
        hostPath:
          path: /
      initContainers:
      - name: disable-smt
        image: ubuntu
        command:
        - /bin/bash
        - -c
        - |
          function disable_smt_cos {
            local -r dir="$(mktemp -d)"
            mount /dev/sda12 "${dir}"
            sed -i -e "s|cros_efi|cros_efi nosmt|g" "${dir}/efi/boot/grub.cfg"
            umount "${dir}"
            rmdir "${dir}"
          }
          function disable_smt_ubuntu {
            echo 'GRUB_CMDLINE_LINUX_DEFAULT="nosmt ${GRUB_CMDLINE_LINUX_DEFAULT}"' > /host/etc/default/grub.d/99-nosmt.cfg
            chroot /host /usr/sbin/update-grub
          }
          function disable_smt {
            if grep " nosmt " /proc/cmdline; then
              echo "SMT has been disabled"
              return
            fi
            source /host/etc/os-release
            echo "Attempting to disable SMT for ${NAME}"
            case "${NAME}" in
              "Ubuntu") disable_smt_ubuntu;;
              "Container-Optimized OS") disable_smt_cos;;
              *);;
            esac
            echo "SMT disabled, rebooting for it to take effect"
            chroot /host systemctl reboot
          }
          disable_smt
        volumeMounts:
        - name: host
          mountPath: /host
        resources:
          requests:
            memory: 5Mi
            cpu: 5m
        securityContext:
          privileged: true
      containers:
      - image: gcr.io/google-containers/pause:2.0
        name: pause
      # Ensures that the pods will only run on the nodes having the certain
      # label.
      nodeSelector:
        "cloud.google.com/gke-smt-disabled": "true"
