Repository: kubernetes-sigs/azuredisk-csi-driver
Pull request #1596 (2022-11-13 12:11:09)

feat: support perf profile device setting on Linux node
<!--  Thanks for sending a pull request!  Here are some tips for you:

1. If this is your first time, please read our contributor guidelines: https://git.k8s.io/community/contributors/guide#your-first-contribution and developer guide https://git.k8s.io/community/contributors/devel/development.md#development-guide
2. Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request. For reference on required PR/issue labels, read here:
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-release/release.md#issue-kind-label
3. Ensure you have added or ran the appropriate tests for your PR: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/testing.md
4. If you want *faster* PR reviews, read how: https://git.k8s.io/community/contributors/guide/pull-requests.md#best-practices-for-faster-reviews
5. Follow the instructions for writing a release note: https://git.k8s.io/community/contributors/guide/release-notes.md
6. If the PR is unfinished, see how to mark it: https://git.k8s.io/community/contributors/guide/pull-requests.md#marking-unfinished-pull-requests
-->

**What type of PR is this?**
/kind feature

**What this PR does / why we need it**:
feat: support perf profile device setting on Linux node

**Which issue(s) this PR fixes**:
<!-- 
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
Fixes #

**Requirements**:
- [ ] uses [conventional commit messages](https://www.conventionalcommits.org/)
  <!-- Common commit types:
        build: Build 🏭
        chore: Maintenance 🔧
        ci: Continuous Integration 💜
        docs: Documentation 📘
        feat: Features 🌈
        fix: Bug Fixes 🐞
        perf: Performance Improvements 🚀
        refactor: Code Refactoring 💎
        revert: Revert Change ◀️
        style: Code Style 🎶
        security: Security Fix 🛡️
        test: Testing 💚 -->
- [ ] includes documentation
- [ ] adds unit tests
- [ ] tested upgrade from previous version

**Special notes for your reviewer**:


**Release note**:
```
feat: support perf profile
```


k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/azuredisk-csi-driver/pull/1596#" title="Author self-approved">andyzhangx</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fazuredisk-csi-driver).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/azuredisk-csi-driver/blob/master/OWNERS)~~ [andyzhangx]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
k8s-ci-robot: @andyzhangx: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-azuredisk-csi-driver-verify | ec54fbf881aea603ae85cd4a5b99e35199defcd7 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_azuredisk-csi-driver/1596/pull-azuredisk-csi-driver-verify/1591765617591980032) | true | `/test pull-azuredisk-csi-driver-verify`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=azuredisk-csi-driver&pr=1596). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aandyzhangx). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/azuredisk-csi-driver/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/README.md b/README.md
index 60568427b..ec8f48ed0 100644
--- a/README.md
+++ b/README.md
@@ -77,13 +77,12 @@ follow guide [here](./docs/install-driver-on-aks.md)
 - [Shared Disk](./deploy/example/sharedisk)
 - [Volume Limits](./deploy/example/volumelimits)
 - [fsGroupPolicy](./deploy/example/fsgroup)
-- [Tune disk performance on Linux](./docs/perf-profiles.md)
+- [Advanced disk performance tuning (Preview)](./docs/perf-profiles.md)
 
 #### New in V2
 
 - [Attachments Replicas for Faster Pod Failover (Preview)](./docs/design-v2.md)
   - See [pod failover demo](./deploy/example/failover/README.md) for example configuration.
-- [Advanced disk performance tuning (Preview)](./docs/perf-profiles.md)
 
 ### Troubleshooting
 
diff --git a/docs/driver-parameters.md b/docs/driver-parameters.md
index dbf1342e7..6418382c6 100644
--- a/docs/driver-parameters.md
+++ b/docs/driver-parameters.md
@@ -23,7 +23,7 @@ tags | azure disk [tags](https://docs.microsoft.com/en-us/azure/azure-resource-m
 diskEncryptionSetID | ResourceId of the disk encryption set to use for [enabling encryption at rest](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/disk-encryption) | format: `/subscriptions/{subs-id}/resourceGroups/{rg-name}/providers/Microsoft.Compute/diskEncryptionSets/{diskEncryptionSet-name}` | No | ""
 diskEncryptionType | encryption type of the disk encryption set | `EncryptionAtRestWithCustomerKey`(by default), `EncryptionAtRestWithPlatformAndCustomerKeys` | No | ""
 writeAcceleratorEnabled | [Write Accelerator on Azure Disks](https://docs.microsoft.com/azure/virtual-machines/windows/how-to-enable-write-accelerator) | `true`, `false` | No | ""
-perfProfile | [Block device performance tuning using perfProfiles](./perf-profiles.md) | `none`, `basic` | No | `none`
+perfProfile | [Block device performance tuning using perfProfiles](./perf-profiles.md) | `none`, `basic`, `advanced` | No | `none`
 networkAccessPolicy | NetworkAccessPolicy property to prevent anybody from generating the SAS URI for a disk or a snapshot | `AllowAll`, `DenyAll`, `AllowPrivate` | No | `AllowAll`
 diskAccessID | ARM id of the DiskAccess resource for using private endpoints on disks | | No  | ``
 enableBursting | [enable on-demand bursting](https://docs.microsoft.com/en-us/azure/virtual-machines/disk-bursting) beyond the provisioned performance target of the disk. On-demand bursting only be applied to Premium disk, disk size > 512GB, Ultra & shared disk is not supported. Bursting is disabled by default. | `true`, `false` | No | `false`
@@ -48,7 +48,6 @@ In addition to the parameters supported by the V1 driver, Azure Disk CSI driver
 
 Name | Meaning | Available Value | Mandatory | Default value
 --- | --- | --- | --- | ---
-perfProfile | [Block device performance tuning using perfProfiles](./perf-profiles.md) | `none`, `basic`, `advanced` | No | `none`
 enableAsyncAttach | The V2 driver uses a different strategy to manage Azure API throttling and ignores this parameter. | N/A | No | N/A
 maxShares | The total number of shared disk mounts allowed for the disk. Setting the value to 2 or more enables attachment replicas. | Supported values depend on the disk size. See [Share an Azure managed disk](https://docs.microsoft.com/en-us/azure/virtual-machines/disks-shared) for supported values. | No | 1
 maxMountReplicaCount | The number of replicas attachments to maintain. | This value must be in the range `[0..(maxShares - 1)]` | No        | If `accessMode` is `ReadWriteMany`, the default is `0`. Otherwise, the default is `maxShares - 1` |
diff --git a/docs/install-csi-driver-v0.10.0.md b/docs/install-csi-driver-v0.10.0.md
new file mode 100644
index 000000000..63a201b9a
--- /dev/null
+++ b/docs/install-csi-driver-v0.10.0.md
@@ -0,0 +1,36 @@
+## Install CSI driver development version on a Kubernetes cluster
+
+### Install by kubectl
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.10.0/deploy/install-driver.sh | bash -s v0.10.0 --
+```
+
+ - Enable snapshot support
+> Note: only available from v1.17.0
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.10.0/deploy/install-driver.sh | bash -s v0.10.0 snapshot --
+```
+
+### Check pods status:
+
+```console
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```console
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-controller-56bfddd689-7s8yg       6/6     Running   0          35s     10.240.0.29    k8s-agentpool-22533604-1
+csi-snapshot-controller-84db6dbbb-stzwr         6/6     Running   0          41s     10.240.0.17    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+### Clean up CSI driver
+
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.10.0/deploy/uninstall-driver.sh | bash -s v0.10.0 --
+```
diff --git a/docs/install-csi-driver-v0.2.0.md b/docs/install-csi-driver-v0.2.0.md
new file mode 100644
index 000000000..453c77e07
--- /dev/null
+++ b/docs/install-csi-driver-v0.2.0.md
@@ -0,0 +1,38 @@
+# Install azuredisk CSI driveri v0.2.0-alpha on a Kubernetes cluster
+
+## Installation with kubectl
+
+```
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/crd-csi-driver-registry.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/crd-csi-node-info.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/rbac-csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/csi-azuredisk-node.yaml
+```
+
+- check pods status:
+
+```
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+- clean up azure disk CSI driver
+
+```
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/csi-azuredisk-controller.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/csi-azuredisk-node.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/crd-csi-driver-registry.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/crd-csi-node-info.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.2.0/rbac-csi-azuredisk-controller.yaml
+```
+
diff --git a/docs/install-csi-driver-v0.3.0.md b/docs/install-csi-driver-v0.3.0.md
new file mode 100644
index 000000000..dea1767f1
--- /dev/null
+++ b/docs/install-csi-driver-v0.3.0.md
@@ -0,0 +1,38 @@
+# Install azuredisk CSI driver v0.3.0 on a Kubernetes cluster
+
+## Installation with kubectl
+
+```
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/crd-csi-driver-registry.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/crd-csi-node-info.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/rbac-csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/csi-azuredisk-node.yaml
+```
+
+- check pods status:
+
+```
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+- clean up azure disk CSI driver
+
+```
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/csi-azuredisk-controller.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/csi-azuredisk-node.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/crd-csi-driver-registry.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/crd-csi-node-info.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.3.0/rbac-csi-azuredisk-controller.yaml
+```
+
diff --git a/docs/install-csi-driver-v0.4.0.md b/docs/install-csi-driver-v0.4.0.md
new file mode 100644
index 000000000..306751230
--- /dev/null
+++ b/docs/install-csi-driver-v0.4.0.md
@@ -0,0 +1,38 @@
+# Install azuredisk CSI driver v0.4.0 on a Kubernetes cluster
+
+## Installation with kubectl
+
+```
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/crd-csi-driver-registry.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/crd-csi-node-info.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/rbac-csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/csi-azuredisk-node.yaml
+```
+
+- check pods status:
+
+```
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+- clean up azure disk CSI driver
+
+```
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/csi-azuredisk-controller.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/csi-azuredisk-node.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/crd-csi-driver-registry.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/crd-csi-node-info.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.4.0/rbac-csi-azuredisk-controller.yaml
+```
+
diff --git a/docs/install-csi-driver-v0.5.0.md b/docs/install-csi-driver-v0.5.0.md
new file mode 100644
index 000000000..2bdfa5077
--- /dev/null
+++ b/docs/install-csi-driver-v0.5.0.md
@@ -0,0 +1,40 @@
+# Install azuredisk CSI driver v0.5.0 on a Kubernetes cluster
+
+## Installation with kubectl
+
+```
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/crd-csi-driver-registry.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/crd-csi-node-info.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/rbac-csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/csi-azuredisk-controller.yaml
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/csi-azuredisk-node.yaml
+```
+
+- check pods status:
+
+```
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-controller-56bfddd689-k8cm5       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-1
+csi-azuredisk-controller-56bfddd689-nhzl5       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+- clean up azure disk CSI driver
+
+```
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/csi-azuredisk-controller.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/csi-azuredisk-node.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/crd-csi-driver-registry.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/crd-csi-node-info.yaml
+kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/v0.5.0/rbac-csi-azuredisk-controller.yaml
+```
+
diff --git a/docs/install-csi-driver-v0.6.0.md b/docs/install-csi-driver-v0.6.0.md
new file mode 100644
index 000000000..241fcc38d
--- /dev/null
+++ b/docs/install-csi-driver-v0.6.0.md
@@ -0,0 +1,36 @@
+# Install azuredisk CSI driver v0.6.0 on a Kubernetes cluster
+
+### Install by kubectl
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.6.0/deploy/install-driver.sh | bash -s v0.6.0 --
+```
+
+ - Enable snapshot support
+> Note: only available from v1.17.0
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.6.0/deploy/install-driver.sh | bash -s v0.6.0 snapshot --
+```
+
+### Check pods status:
+
+```console
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```console
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-controller-56bfddd689-7s8yg       6/6     Running   0          35s     10.240.0.29    k8s-agentpool-22533604-1
+csi-snapshot-controller-84db6dbbb-stzwr         6/6     Running   0          41s     10.240.0.17    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+### Clean up CSI driver
+
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.6.0/deploy/uninstall-driver.sh | bash -s v0.6.0 --
+```
diff --git a/docs/install-csi-driver-v0.7.0.md b/docs/install-csi-driver-v0.7.0.md
new file mode 100644
index 000000000..8854459a8
--- /dev/null
+++ b/docs/install-csi-driver-v0.7.0.md
@@ -0,0 +1,36 @@
+## Install CSI driver v0.7.0 version on a Kubernetes cluster
+
+### Install by kubectl
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.7.0/deploy/install-driver.sh | bash -s v0.7.0 --
+```
+
+ - Enable snapshot support
+> Note: only available from v1.17.0
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.7.0/deploy/install-driver.sh | bash -s v0.7.0 snapshot --
+```
+
+### Check pods status:
+
+```console
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```console
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-controller-56bfddd689-7s8yg       6/6     Running   0          35s     10.240.0.29    k8s-agentpool-22533604-1
+csi-snapshot-controller-84db6dbbb-stzwr         6/6     Running   0          41s     10.240.0.17    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+### Clean up CSI driver
+
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.7.0/deploy/uninstall-driver.sh | bash -s v0.7.0 --
+```
diff --git a/docs/install-csi-driver-v0.8.0.md b/docs/install-csi-driver-v0.8.0.md
new file mode 100644
index 000000000..5b8a86f02
--- /dev/null
+++ b/docs/install-csi-driver-v0.8.0.md
@@ -0,0 +1,36 @@
+## Install CSI driver development version on a Kubernetes cluster
+
+### Install by kubectl
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.8.0/deploy/install-driver.sh | bash -s v0.8.0 --
+```
+
+ - Enable snapshot support
+> Note: only available from v1.17.0
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.8.0/deploy/install-driver.sh | bash -s v0.8.0 snapshot --
+```
+
+### Check pods status:
+
+```console
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```console
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-controller-56bfddd689-7s8yg       6/6     Running   0          35s     10.240.0.29    k8s-agentpool-22533604-1
+csi-snapshot-controller-84db6dbbb-stzwr         6/6     Running   0          41s     10.240.0.17    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+### Clean up CSI driver
+
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.8.0/deploy/uninstall-driver.sh | bash -s v0.8.0 --
+```
diff --git a/docs/install-csi-driver-v0.9.0.md b/docs/install-csi-driver-v0.9.0.md
new file mode 100644
index 000000000..786b6a86a
--- /dev/null
+++ b/docs/install-csi-driver-v0.9.0.md
@@ -0,0 +1,36 @@
+## Install CSI driver development version on a Kubernetes cluster
+
+### Install by kubectl
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.9.0/deploy/install-driver.sh | bash -s v0.9.0 --
+```
+
+ - Enable snapshot support
+> Note: only available from v1.17.0
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.9.0/deploy/install-driver.sh | bash -s v0.9.0 snapshot --
+```
+
+### Check pods status:
+
+```console
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-controller
+kubectl -n kube-system get pod -o wide --watch -l app=csi-azuredisk-node
+```
+
+example output:
+
+```console
+NAME                                            READY   STATUS    RESTARTS   AGE     IP             NODE
+csi-azuredisk-controller-56bfddd689-dh5tk       6/6     Running   0          35s     10.240.0.19    k8s-agentpool-22533604-0
+csi-azuredisk-controller-56bfddd689-7s8yg       6/6     Running   0          35s     10.240.0.29    k8s-agentpool-22533604-1
+csi-snapshot-controller-84db6dbbb-stzwr         6/6     Running   0          41s     10.240.0.17    k8s-agentpool-22533604-0
+csi-azuredisk-node-cvgbs                        3/3     Running   0          7m4s    10.240.0.35    k8s-agentpool-22533604-1
+csi-azuredisk-node-dr4s4                        3/3     Running   0          7m4s    10.240.0.4     k8s-agentpool-22533604-0
+```
+
+### Clean up CSI driver
+
+```console
+curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/v0.9.0/deploy/uninstall-driver.sh | bash -s v0.9.0 --
+```
diff --git a/docs/perf-profiles.md b/docs/perf-profiles.md
index dad24884e..2bdf23cbb 100644
--- a/docs/perf-profiles.md
+++ b/docs/perf-profiles.md
@@ -19,7 +19,7 @@
 Azure storage publishes [guidelines](https://docs.microsoft.com/en-us/azure/virtual-machines/premium-storage-performance)
 for the applications to configure the disks' guest OS settings to drive maximum IOPS and Bandwidth.
 
-Azure Disk CSI driver v2 allows customers to tweak the guest OS device settings using perfProfile feature.
+Azure Disk CSI driver allows customers to tweak the guest OS device settings using perfProfile feature.
 Users can chose from a list of `perfProfile` to tweak the IO behavior of their block devices in accordance with their workloads.
 
 `perfProfile` can be set at the `StorageClass` level and applies to all the disks created using the `StorageClass`
@@ -42,7 +42,7 @@ metadata:
 provisioner: disk.csi.azure.com
 parameters:
   skuName: Premium_LRS
-  perfProfile: Basic # available values: "None" (default) and "Basic". The V2 driver adds "Advanced". These values are case insensitive.
+  perfProfile: Basic # available values: "None"(default), "Basic", "Advanced" (case insensitive)
 reclaimPolicy: Delete
 volumeBindingMode: Immediate
 allowVolumeExpansion: true
@@ -50,7 +50,7 @@ allowVolumeExpansion: true
 
 ### Advanced
 
-> Available with v2.0.0-alpha.1+
+> Available with v1.25.0+
 
 `Advanced` `perfProfile` gives users the ultimate flexibility to tweak any device setting they desire, to optimize the disk IOs for their workload.
 
@@ -116,11 +116,7 @@ allowVolumeExpansion: true
 
 Consider `StorageClass` `sc-test-postgresql-p20-optimized` in below example, which can optimize a p20 azure disk to get increased combined throughput, IOPS and better IO latency for a PostresSQL inspired fio workload.
 
-To try the optimizations, follow below step:
-
-- Create an aks cluster with `Standard_D4s_v4` VM SKU nodepool.
-
-- Install azuredisk CSI driver v2 using instructions [here](https://github.com/kubernetes-sigs/azuredisk-csi-driver/tree/main_v2/charts).
+To try the optimizations, follow below steps:
 
 - Install kubestone.
 
@@ -307,16 +303,6 @@ kubectl delete namespace kubestone --ignore-not-found
 kustomize build github.com/xridge/kubestone/config/default?ref=v0.5.0 | sed "s/kubestone:latest/kubestone:v0.5.0/" | kubectl delete --ignore-not-found -f -
 ```
 
-- To delete StorageClass
-
-```console
-kubectl delete sc sc-test-postgresql-p20 --ignore-not-found
-
-kubectl delete sc sc-test-postgresql-p20-optimized --ignore-not-found
-```
-
-- To uninstall azuredisk CSI driver v2 use instructions [here](https://github.com/kubernetes-sigs/azuredisk-csi-driver/tree/main_v2/charts)
-
 ## Limitations
 
 - This feature is not supported for HDD or UltraDisk right now.
@@ -326,4 +312,4 @@ kubectl delete sc sc-test-postgresql-p20-optimized --ignore-not-found
 ## Caution
 
 - This feature is currently in `alpha` and customers are advised to not use this feature in their production workloads.
-- Device tuned using the `Basic` and `Advanced` `perfProfile` options can show variance in performance due to several factors including (but not limited to) disk size, VM SKU, disk caching mode, linux distribution and kernel version, workload type. Customers are advised to test the `perfProfile` they chose in the controlled environment to ascertain the performance benefits, before using them.
+- Device tuned using the `Basic` and `Advanced` `perfProfile` options can show variance in performance due to several factors including (but not limited to) disk size, VM SKU, disk caching mode, linux distribution and kernel version, workload type. Customers are advised to test the `perfProfile` they chose in the controlled environment to ascertain the performance benefits, before using them.
\ No newline at end of file
diff --git a/pkg/azureconstants/azure_constants.go b/pkg/azureconstants/azure_constants.go
index 914ce88aa..51042a0bd 100644
--- a/pkg/azureconstants/azure_constants.go
+++ b/pkg/azureconstants/azure_constants.go
@@ -46,6 +46,7 @@ const (
 	NetworkAccessPolicyField      = "networkaccesspolicy"
 	NotFound                      = "NotFound"
 	PerfProfileBasic              = "basic"
+	PerfProfileAdvanced           = "advanced"
 	PerfProfileField              = "perfprofile"
 	PerfProfileNone               = "none"
 	PremiumAccountPrefix          = "premium"
@@ -85,6 +86,9 @@ const (
 	SourceResourceID              = "source_resource_id"
 	SnapshotName                  = "snapshot_name"
 	SnapshotID                    = "snapshot_id"
+	DeviceSettingsKeyPrefix       = "device-setting/"
+	BlockDeviceRootPathLinux      = "/sys/block"
+	DummyBlockDevicePathLinux     = "/sys/block/sda"
 	// define different sleep time when hit throttling
 	SnapshotOpThrottlingSleepSec = 50
 )
diff --git a/pkg/azuredisk/controllerserver.go b/pkg/azuredisk/controllerserver.go
index bd2936a0c..d37075066 100644
--- a/pkg/azuredisk/controllerserver.go
+++ b/pkg/azuredisk/controllerserver.go
@@ -39,6 +39,7 @@ import (
 	"sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
 	consts "sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
 	"sigs.k8s.io/azuredisk-csi-driver/pkg/azureutils"
+	"sigs.k8s.io/azuredisk-csi-driver/pkg/optimization"
 	volumehelper "sigs.k8s.io/azuredisk-csi-driver/pkg/util"
 	"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
 	azure "sigs.k8s.io/cloud-provider-azure/pkg/provider"
@@ -75,6 +76,13 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
 	if !azureutils.IsValidVolumeCapabilities(volCaps, diskParams.MaxShares) {
 		return nil, status.Error(codes.InvalidArgument, "Volume capability not supported")
 	}
+	isAdvancedPerfProfile := strings.EqualFold(diskParams.PerfProfile, azureconstants.PerfProfileAdvanced)
+	// If perfProfile is set to advanced and no/invalid device settings are provided, fail the request
+	if d.getPerfOptimizationEnabled() && isAdvancedPerfProfile {
+		if err := optimization.AreDeviceSettingsValid(azureconstants.DummyBlockDevicePathLinux, diskParams.DeviceSettings); err != nil {
+			return nil, status.Error(codes.InvalidArgument, err.Error())
+		}
+	}
 
 	if acquired := d.volumeLocks.TryAcquire(name); !acquired {
 		return nil, status.Errorf(codes.Aborted, volumeOperationAlreadyExistsFmt, name)
diff --git a/pkg/azuredisk/controllerserver_v2.go b/pkg/azuredisk/controllerserver_v2.go
index 9e3579932..53c62062f 100644
--- a/pkg/azuredisk/controllerserver_v2.go
+++ b/pkg/azuredisk/controllerserver_v2.go
@@ -42,6 +42,7 @@ import (
 	"sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
 	consts "sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
 	"sigs.k8s.io/azuredisk-csi-driver/pkg/azureutils"
+	"sigs.k8s.io/azuredisk-csi-driver/pkg/optimization"
 	volumehelper "sigs.k8s.io/azuredisk-csi-driver/pkg/util"
 	"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
 	azure "sigs.k8s.io/cloud-provider-azure/pkg/provider"
@@ -72,6 +73,13 @@ func (d *DriverV2) CreateVolume(ctx context.Context, req *csi.CreateVolumeReques
 	if !azureutils.IsValidVolumeCapabilities(volCaps, diskParams.MaxShares) {
 		return nil, status.Error(codes.InvalidArgument, "Volume capability not supported")
 	}
+	isAdvancedPerfProfile := strings.EqualFold(diskParams.PerfProfile, azureconstants.PerfProfileAdvanced)
+	// If perfProfile is set to advanced and no/invalid device settings are provided, fail the request
+	if d.getPerfOptimizationEnabled() && isAdvancedPerfProfile {
+		if err := optimization.AreDeviceSettingsValid(azureconstants.DummyBlockDevicePathLinux, diskParams.DeviceSettings); err != nil {
+			return nil, status.Error(codes.InvalidArgument, err.Error())
+		}
+	}
 
 	if acquired := d.volumeLocks.TryAcquire(name); !acquired {
 		return nil, status.Errorf(codes.Aborted, volumeOperationAlreadyExistsFmt, name)
diff --git a/pkg/azuredisk/nodeserver.go b/pkg/azuredisk/nodeserver.go
index 241213ab4..10082b035 100644
--- a/pkg/azuredisk/nodeserver.go
+++ b/pkg/azuredisk/nodeserver.go
@@ -102,14 +102,14 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe
 	// If perf optimizations are enabled
 	// tweak device settings to enhance performance
 	if d.getPerfOptimizationEnabled() {
-		profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, err := optimization.GetDiskPerfAttributes(req.GetVolumeContext())
+		profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettings, err := optimization.GetDiskPerfAttributes(req.GetVolumeContext())
 		if err != nil {
 			return nil, status.Errorf(codes.Internal, "failed to get perf attributes for %s. Error: %v", source, err)
 		}
 
 		if d.getDeviceHelper().DiskSupportsPerfOptimization(profile, accountType) {
 			if err := d.getDeviceHelper().OptimizeDiskPerformance(d.getNodeInfo(), source, profile, accountType,
-				diskSizeGibStr, diskIopsStr, diskBwMbpsStr); err != nil {
+				diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettings); err != nil {
 				return nil, status.Errorf(codes.Internal, "failed to optimize device performance for target(%s) error(%s)", source, err)
 			}
 		} else {
diff --git a/pkg/azuredisk/nodeserver_v2.go b/pkg/azuredisk/nodeserver_v2.go
index 62defda58..7951fae85 100644
--- a/pkg/azuredisk/nodeserver_v2.go
+++ b/pkg/azuredisk/nodeserver_v2.go
@@ -90,14 +90,14 @@ func (d *DriverV2) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolume
 	// If perf optimizations are enabled
 	// tweak device settings to enhance performance
 	if d.getPerfOptimizationEnabled() {
-		profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, err := optimization.GetDiskPerfAttributes(req.GetVolumeContext())
+		profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettings, err := optimization.GetDiskPerfAttributes(req.GetVolumeContext())
 		if err != nil {
 			return nil, status.Errorf(codes.Internal, "failed to get perf attributes for %s. Error: %v", source, err)
 		}
 
 		if d.getDeviceHelper().DiskSupportsPerfOptimization(profile, accountType) {
 			if err := d.getDeviceHelper().OptimizeDiskPerformance(d.getNodeInfo(), source, profile, accountType,
-				diskSizeGibStr, diskIopsStr, diskBwMbpsStr); err != nil {
+				diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettings); err != nil {
 				return nil, status.Errorf(codes.Internal, "failed to optimize device performance for target(%s) error(%s)", source, err)
 			}
 		} else {
diff --git a/pkg/azureutils/azure_disk_utils.go b/pkg/azureutils/azure_disk_utils.go
index f3bc1f036..2bc91522b 100644
--- a/pkg/azureutils/azure_disk_utils.go
+++ b/pkg/azureutils/azure_disk_utils.go
@@ -20,6 +20,7 @@ import (
 	"errors"
 	"fmt"
 	"os"
+	"path/filepath"
 	"regexp"
 	"strconv"
 	"strings"
@@ -102,6 +103,7 @@ var (
 type ManagedDiskParameters struct {
 	AccountType             string
 	CachingMode             v1.AzureDataDiskCachingMode
+	DeviceSettings          map[string]string
 	DiskAccessID            string
 	DiskEncryptionSetID     string
 	DiskEncryptionType      string
@@ -537,9 +539,10 @@ func ParseDiskParameters(parameters map[string]string) (ManagedDiskParameters, e
 	}
 
 	diskParams := ManagedDiskParameters{
-		Incremental:   true, //true by default
-		Tags:          make(map[string]string),
-		VolumeContext: parameters,
+		DeviceSettings: make(map[string]string),
+		Incremental:    true, //true by default
+		Tags:           make(map[string]string),
+		VolumeContext:  parameters,
 	}
 	for k, v := range parameters {
 		switch strings.ToLower(k) {
@@ -623,7 +626,13 @@ func ParseDiskParameters(parameters map[string]string) (ManagedDiskParameters, e
 		case consts.ZonedField:
 			// no op, only for backward compatibility with in-tree driver
 		default:
-			return diskParams, fmt.Errorf("invalid parameter %s in storage class", k)
+			// accept all device settings params
+			// device settings need to start with azureconstants.DeviceSettingsKeyPrefix
+			if deviceSettings, err := optimization.GetDeviceSettingFromAttribute(k); err == nil {
+				diskParams.DeviceSettings[filepath.Join(consts.DummyBlockDevicePathLinux, deviceSettings)] = v
+			} else {
+				return diskParams, fmt.Errorf("invalid parameter %s in storage class", k)
+			}
 		}
 	}
 	return diskParams, nil
diff --git a/pkg/optimization/device_perf.go b/pkg/optimization/device_perf.go
index 99f91331a..ee7b991b0 100644
--- a/pkg/optimization/device_perf.go
+++ b/pkg/optimization/device_perf.go
@@ -16,24 +16,22 @@ limitations under the License.
 
 package optimization
 
+import consts "sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
+
 // This is the interface for DeviceHelper
 type Interface interface {
 	DiskSupportsPerfOptimization(diskPerfProfile, diskAccountType string) bool
 	OptimizeDiskPerformance(nodeInfo *NodeInfo,
-		devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string) error
+		devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string, deviceSettingsFromCtx map[string]string) error
 }
 
-const (
-	blockDeviceRootPathDefault = "/sys/block"
-)
-
 // Compile-time check to ensure all Mounter DeviceHelper satisfy
 // the DeviceHelper interface.
-var _ Interface = &DeviceHelper{blockDeviceRootPath: blockDeviceRootPathDefault}
+var _ Interface = &DeviceHelper{blockDeviceRootPath: consts.BlockDeviceRootPathLinux}
 
 func NewSafeDeviceHelper() *SafeDeviceHelper {
 	return &SafeDeviceHelper{
-		Interface: &DeviceHelper{blockDeviceRootPath: blockDeviceRootPathDefault},
+		Interface: &DeviceHelper{blockDeviceRootPath: consts.BlockDeviceRootPathLinux},
 	}
 }
 
@@ -47,6 +45,6 @@ func (dh *SafeDeviceHelper) DeviceSupportsPerfOptimization(diskPerfProfile, disk
 }
 
 func (dh *SafeDeviceHelper) OptimizeDiskPerformance(nodeInfo *NodeInfo,
-	devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string) error {
-	return dh.Interface.OptimizeDiskPerformance(nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr)
+	devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string, deviceSettingsFromCtx map[string]string) error {
+	return dh.Interface.OptimizeDiskPerformance(nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettingsFromCtx)
 }
diff --git a/pkg/optimization/device_perf_helper.go b/pkg/optimization/device_perf_helper.go
index 9dd8da737..a24994aab 100644
--- a/pkg/optimization/device_perf_helper.go
+++ b/pkg/optimization/device_perf_helper.go
@@ -18,6 +18,7 @@ package optimization
 
 import (
 	"fmt"
+	"path/filepath"
 	"strings"
 
 	consts "sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
@@ -27,13 +28,15 @@ import (
 // Right now we are only supporting basic profile
 // Other advanced profiles to come later
 func IsValidPerfProfile(profile string) bool {
-	return strings.EqualFold(profile, consts.PerfProfileBasic) || strings.EqualFold(profile, consts.PerfProfileNone)
+	return isPerfTuningEnabled(profile) || strings.EqualFold(profile, consts.PerfProfileNone)
 }
 
 // getDiskPerfAttributes gets the per tuning mode and profile set in attributes
-func GetDiskPerfAttributes(attributes map[string]string) (profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string, err error) {
+func GetDiskPerfAttributes(attributes map[string]string) (profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string, deviceSettings map[string]string, err error) {
+	deviceSettings = make(map[string]string)
 	perfProfilePresent := false
 	for k, v := range attributes {
+		key := strings.ToLower(k)
 		switch strings.ToLower(k) {
 		case consts.PerfProfileField:
 			perfProfilePresent = true
@@ -47,7 +50,9 @@ func GetDiskPerfAttributes(attributes map[string]string) (profile, accountType,
 		case consts.DiskMBPSReadWriteField:
 			diskBwMbpsStr = v
 		default:
-			continue
+			if setting, err := GetDeviceSettingFromAttribute(key); err == nil {
+				deviceSettings[setting] = v
+			}
 		}
 	}
 
@@ -55,7 +60,7 @@ func GetDiskPerfAttributes(attributes map[string]string) (profile, accountType,
 	if perfProfilePresent {
 		// Make sure it's a valid perf profile
 		if !IsValidPerfProfile(profile) {
-			return profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, fmt.Errorf("Perf profile %s is invalid", profile)
+			return profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettings, fmt.Errorf("Perf profile %s is invalid", profile)
 		}
 	} else {
 		// if perfProfile parameter was not provided in the attributes
@@ -63,7 +68,7 @@ func GetDiskPerfAttributes(attributes map[string]string) (profile, accountType,
 		profile = consts.PerfProfileNone
 	}
 
-	return profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, nil
+	return profile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettings, nil
 }
 
 // isPerfTuningEnabled checks to see if perf tuning is enabled
@@ -71,6 +76,8 @@ func isPerfTuningEnabled(profile string) bool {
 	switch strings.ToLower(profile) {
 	case consts.PerfProfileBasic:
 		return true
+	case consts.PerfProfileAdvanced:
+		return true
 	default:
 		return false
 	}
@@ -84,3 +91,34 @@ func accountSupportsPerfOptimization(accountType string) bool {
 	}
 	return false
 }
+
+// Gets device setting from the Disk attribute/param but trimming the consts.DeviceSettingsKeyPrefix prefix
+func GetDeviceSettingFromAttribute(key string) (deviceSetting string, err error) {
+	if !strings.HasPrefix(key, consts.DeviceSettingsKeyPrefix) {
+		return key, fmt.Errorf("GetDeviceSettingFromAttribute: %s is not a valid device setting override", key)
+	}
+	return strings.TrimPrefix(key, consts.DeviceSettingsKeyPrefix), nil
+}
+
+// Checks to see if deviceSettings passed are valid
+func AreDeviceSettingsValid(deviceRoot string, deviceSettings map[string]string) error {
+	if len(deviceSettings) == 0 {
+		return fmt.Errorf("AreDeviceSettingsValid: No deviceSettings passed")
+	}
+
+	for setting := range deviceSettings {
+		// Use absolute setting path
+		absSetting, err := filepath.Abs(setting)
+		if err != nil {
+			return fmt.Errorf("AreDeviceSettingsValid: Failed to get absolute path. Can not allow setting %s for device %s",
+				setting,
+				deviceRoot)
+		}
+
+		if !strings.HasPrefix(absSetting, filepath.Clean(deviceRoot)+"/") {
+			return fmt.Errorf("AreDeviceSettingsValid: Setting %s is not a valid file path under %s", setting, deviceRoot)
+		}
+	}
+
+	return nil
+}
diff --git a/pkg/optimization/device_perf_linux.go b/pkg/optimization/device_perf_linux.go
index a75e91a7b..6366657c4 100644
--- a/pkg/optimization/device_perf_linux.go
+++ b/pkg/optimization/device_perf_linux.go
@@ -29,6 +29,8 @@ import (
 	"strings"
 
 	"k8s.io/klog/v2"
+
+	consts "sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
 )
 
 type DeviceHelper struct {
@@ -36,7 +38,7 @@ type DeviceHelper struct {
 }
 
 func NewDeviceHelper() *DeviceHelper {
-	return &DeviceHelper{blockDeviceRootPath: blockDeviceRootPathDefault}
+	return &DeviceHelper{blockDeviceRootPath: consts.BlockDeviceRootPathLinux}
 }
 
 func (deviceHelper *DeviceHelper) DiskSupportsPerfOptimization(diskPerfProfile, diskAccountType string) bool {
@@ -45,79 +47,89 @@ func (deviceHelper *DeviceHelper) DiskSupportsPerfOptimization(diskPerfProfile,
 
 // OptimizeDiskPerformance optimizes device performance by setting tuning block device settings
 func (deviceHelper *DeviceHelper) OptimizeDiskPerformance(nodeInfo *NodeInfo, devicePath,
-	perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string) (err error) {
-	klog.V(2).Infof("OptimizeDiskPerformance: Tuning settings for %s", devicePath)
+	perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string, deviceSettingsFromCtx map[string]string) (err error) {
 
 	if nodeInfo == nil {
 		return fmt.Errorf("OptimizeDiskPerformance: Node info is not provided. Error: invalid parameter")
 	}
 
-	queueDepth, nrRequests, scheduler, maxSectorsKb, readAheadKb, err := getOptimalDeviceSettings(nodeInfo, DiskSkuMap, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr)
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Failed to get optimal settings for profile %s accountType %s device %s Error: %v", perfProfile, accountType, devicePath, err)
-	}
-
 	deviceName, err := getDeviceName(devicePath)
 	if err != nil {
 		return fmt.Errorf("OptimizeDiskPerformance: Could not get deviceName for %s. Error: %v", devicePath, err)
 	}
 
-	klog.V(2).Infof("OptimizeDiskPerformance: Tuning settings for devicePath %s, deviceName %s, profile %s queueDepth %s nrRequests %s scheduler %s maxSectorsKb %s readAheadKb %s",
-		devicePath,
-		deviceName,
-		perfProfile,
-		queueDepth,
-		nrRequests,
-		scheduler,
-		maxSectorsKb,
-		readAheadKb)
-
-	err = echoToFile(maxSectorsKb, filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/max_sectors_kb"))
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set max_sectors_kb for device %s. Error: %v", deviceName, err)
+	var deviceSettings map[string]string
+	deviceRoot := filepath.Join(deviceHelper.blockDeviceRootPath, deviceName)
+	switch strings.ToLower(perfProfile) {
+	case consts.PerfProfileBasic:
+		deviceSettings, err = getDeviceSettingsForBasicProfile(nodeInfo,
+			deviceRoot, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr)
+	case consts.PerfProfileAdvanced:
+		deviceSettings, err = getDeviceSettingsForAdvancedProfile(deviceRoot, deviceSettingsFromCtx)
+	default:
+		return fmt.Errorf("OptimizeDiskPerformance: Invalid perfProfile %s", perfProfile)
 	}
 
-	err = echoToFile(scheduler, filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/scheduler"))
 	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/scheduler for device %s. Error: %v", deviceName, err)
+		return fmt.Errorf("OptimizeDiskPerformance: Failed to optimize disk for deviceName %s perfProfile %s. Error: %v",
+			deviceName, perfProfile, err)
 	}
 
-	err = echoToFile("1", filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/iosched/fifo_batch"))
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/iosched/fifo_batch for device %s. Error: %v", deviceName, err)
-	}
+	klog.V(2).Infof("OptimizeDiskPerformance: Tuning settings for deviceRoot %s perfProfile %s accountType %s deviceSettings %v",
+		deviceRoot,
+		perfProfile,
+		accountType,
+		deviceSettings)
+	return applyDeviceSettings(deviceRoot, deviceSettings)
+}
 
-	err = echoToFile("1", filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/iosched/writes_starved"))
+func getDeviceSettingsForBasicProfile(nodeInfo *NodeInfo,
+	deviceRoot, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string) (deviceSettings map[string]string, err error) {
+	klog.V(2).Infof("getDeviceSettingsForBasicProfile: Getting settings for deviceRoot %s",
+		deviceRoot)
+	queueDepth, nrRequests, scheduler, maxSectorsKb, _, err := getOptimalDeviceSettings(nodeInfo, DiskSkuMap, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr)
 	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/iosched/writes_starved for device %s. Error: %v", deviceName, err)
+		return nil, fmt.Errorf("getDeviceSettingsForBasicProfile: Failed to get optimal settings for profile %s accountType %s. Error: %v", perfProfile, accountType, err)
 	}
 
-	err = echoToFile(queueDepth, filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "device/queue_depth"))
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/queue_depth for device %s. Error: %v", deviceName, err)
-	}
+	deviceSettings = make(map[string]string)
+	deviceSettings[filepath.Join(deviceRoot, "queue/max_sectors_kb")] = maxSectorsKb
+	deviceSettings[filepath.Join(deviceRoot, "queue/scheduler")] = scheduler
+	deviceSettings[filepath.Join(deviceRoot, "device/queue_depth")] = queueDepth
+	deviceSettings[filepath.Join(deviceRoot, "queue/nr_requests")] = nrRequests
+	deviceSettings[filepath.Join(deviceRoot, "queue/read_ahead_kb")] = "8"
 
-	err = echoToFile(nrRequests, filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/nr_requests"))
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/nr_requests for device %s. Error: %v", deviceName, err)
-	}
+	return deviceSettings, nil
+}
 
-	err = echoToFile(readAheadKb, filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/read_ahead_kb"))
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/read_ahead_kb for device %s. Error: %v", deviceName, err)
+func getDeviceSettingsForAdvancedProfile(deviceRoot string, deviceSettingsFromCtx map[string]string) (deviceSettings map[string]string, err error) {
+	klog.V(2).Infof("getDeviceSettingsForAdvancedProfile: Getting settings for deviceRoot %s deviceSettingsFromCtx %v",
+		deviceRoot,
+		deviceSettingsFromCtx)
+	deviceSettings = make(map[string]string)
+	for setting, value := range deviceSettingsFromCtx {
+		deviceSettings[filepath.Join(deviceRoot, setting)] = value
 	}
 
-	err = echoToFile("0", filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/wbt_lat_usec"))
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/wbt_lat_usec for device %s. Error: %v", deviceName, err)
+	return deviceSettings, nil
+}
+
+func applyDeviceSettings(deviceRoot string, deviceSettings map[string]string) (err error) {
+	if err = AreDeviceSettingsValid(deviceRoot, deviceSettings); err != nil {
+		return err
 	}
 
-	err = echoToFile("0", filepath.Join(deviceHelper.blockDeviceRootPath, deviceName, "queue/rotational"))
-	if err != nil {
-		return fmt.Errorf("OptimizeDiskPerformance: Could not set queue/rotational for device %s. Error: %v", deviceName, err)
+	for setting, value := range deviceSettings {
+		err = echoToFile(value, setting)
+		if err != nil {
+			return fmt.Errorf("applyDeviceSettings: Could not set %s with value %s. Error: %v",
+				setting,
+				value,
+				err)
+		}
 	}
 
-	return err
+	return nil
 }
 
 // getDeviceName gets the device name from the device lunpath
@@ -193,12 +205,12 @@ func getOptimalDeviceSettings(nodeInfo *NodeInfo, diskSkus map[string]map[string
 	qdMaxSeqBw := math.Ceil(maxBurstBw * latencyPerIoToGetMaxBwInSec / rsMinSeqIo)
 
 	// queue_depth needed for random IOs to hit IOPS reserved for them
-	qdMaxRandomIops := math.Ceil(maxBurstIops * iopsHeadRoom * latencyForSmallRandOperationInSec)
+	qdMaxRandomIops := math.Ceil(maxBurstIops * latencyForSmallRandOperationInSec)
 
 	maxSectorsKb = fmt.Sprintf("%g", rsMinSeqIo)
 	scheduler = "mq-deadline"
 
-	qdTotal := fmt.Sprintf("%g", math.Ceil(qdMaxRandomIops+qdMaxSeqBw))
+	qdTotal := fmt.Sprintf("%g", math.Ceil(math.Max(((qdMaxRandomIops*iopsHeadRoom)+qdMaxSeqBw), qdMaxRandomIops)))
 	queueDepth = qdTotal
 	nrRequests = qdTotal
 
diff --git a/pkg/optimization/device_perf_unsupported.go b/pkg/optimization/device_perf_unsupported.go
index 3ccd0468c..2758f58db 100644
--- a/pkg/optimization/device_perf_unsupported.go
+++ b/pkg/optimization/device_perf_unsupported.go
@@ -31,6 +31,6 @@ func (deviceHelper *DeviceHelper) DiskSupportsPerfOptimization(diskPerfProfile,
 }
 
 func (deviceHelper *DeviceHelper) OptimizeDiskPerformance(nodeInfo *NodeInfo,
-	devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string) (err error) {
+	devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string, deviceSettingsFromCtx map[string]string) (err error) {
 	return fmt.Errorf("OptimizeDiskPerformance not implemented")
 }
diff --git a/pkg/optimization/mockoptimization/interface.go b/pkg/optimization/mockoptimization/interface.go
index 79470ab22..0702478a4 100644
--- a/pkg/optimization/mockoptimization/interface.go
+++ b/pkg/optimization/mockoptimization/interface.go
@@ -65,15 +65,15 @@ func (mr *MockInterfaceMockRecorder) DiskSupportsPerfOptimization(diskPerfProfil
 }
 
 // OptimizeDiskPerformance mocks base method.
-func (m *MockInterface) OptimizeDiskPerformance(nodeInfo *optimization.NodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string) error {
+func (m *MockInterface) OptimizeDiskPerformance(nodeInfo *optimization.NodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr string, deviceSettingsFromCtx map[string]string) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OptimizeDiskPerformance", nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr)
+	ret := m.ctrl.Call(m, "OptimizeDiskPerformance", nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettingsFromCtx)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // OptimizeDiskPerformance indicates an expected call of OptimizeDiskPerformance.
-func (mr *MockInterfaceMockRecorder) OptimizeDiskPerformance(nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr interface{}) *gomock.Call {
+func (mr *MockInterfaceMockRecorder) OptimizeDiskPerformance(nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettingsFromCtx interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OptimizeDiskPerformance", reflect.TypeOf((*MockInterface)(nil).OptimizeDiskPerformance), nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OptimizeDiskPerformance", reflect.TypeOf((*MockInterface)(nil).OptimizeDiskPerformance), nodeInfo, devicePath, perfProfile, accountType, diskSizeGibStr, diskIopsStr, diskBwMbpsStr, deviceSettingsFromCtx)
 }


Test patch:
diff --git a/pkg/azuredisk/controllerserver_test.go b/pkg/azuredisk/controllerserver_test.go
index 2cb0283f4..6dafcb04e 100644
--- a/pkg/azuredisk/controllerserver_test.go
+++ b/pkg/azuredisk/controllerserver_test.go
@@ -437,6 +437,28 @@ func TestCreateVolume(t *testing.T) {
 				}
 			},
 		},
+		{
+			name: "[Failure] advanced perfProfile fails if no device settings provided",
+			testFunc: func(t *testing.T) {
+				d, _ := NewFakeDriver(t)
+				d.setPerfOptimizationEnabled(true)
+				stdCapacityRangetest := &csi.CapacityRange{
+					RequiredBytes: volumehelper.GiBToBytes(10),
+					LimitBytes:    volumehelper.GiBToBytes(15),
+				}
+				req := &csi.CreateVolumeRequest{
+					Name:               testVolumeName,
+					VolumeCapabilities: stdVolumeCapabilities,
+					CapacityRange:      stdCapacityRangetest,
+					Parameters:         map[string]string{"perfProfile": "advanced"},
+				}
+				_, err := d.CreateVolume(context.Background(), req)
+				expectedErr := status.Error(codes.InvalidArgument, "AreDeviceSettingsValid: No deviceSettings passed")
+				if !reflect.DeepEqual(err, expectedErr) {
+					t.Errorf("actualErr: (%v), expectedErr: (%v)", err, expectedErr)
+				}
+			},
+		},
 	}
 	for _, tc := range testCases {
 		t.Run(tc.name, tc.testFunc)
diff --git a/pkg/azuredisk/nodeserver_test.go b/pkg/azuredisk/nodeserver_test.go
index 4092dfa69..808ba3362 100644
--- a/pkg/azuredisk/nodeserver_test.go
+++ b/pkg/azuredisk/nodeserver_test.go
@@ -561,7 +561,7 @@ func TestNodeStageVolume(t *testing.T) {
 					DiskSupportsPerfOptimization(gomock.Any(), gomock.Any()).
 					Return(true)
 				mockoptimization.EXPECT().
-					OptimizeDiskPerformance(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
+					OptimizeDiskPerformance(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
 					Return(nil).
 					After(diskSupportsPerfOptimizationCall)
 
@@ -589,7 +589,7 @@ func TestNodeStageVolume(t *testing.T) {
 					DiskSupportsPerfOptimization(gomock.Any(), gomock.Any()).
 					Return(true)
 				mockoptimization.EXPECT().
-					OptimizeDiskPerformance(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
+					OptimizeDiskPerformance(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
 					Return(fmt.Errorf("failed to optimize device performance")).
 					After(diskSupportsPerfOptimizationCall)
 
diff --git a/pkg/azureutils/azure_disk_utils_test.go b/pkg/azureutils/azure_disk_utils_test.go
index b7dcf5537..6da72b346 100644
--- a/pkg/azureutils/azure_disk_utils_test.go
+++ b/pkg/azureutils/azure_disk_utils_test.go
@@ -1368,9 +1368,10 @@ func TestParseDiskParameters(t *testing.T) {
 			name:        "nil disk parameters",
 			inputParams: nil,
 			expectedOutput: ManagedDiskParameters{
-				Incremental:   true,
-				Tags:          make(map[string]string),
-				VolumeContext: make(map[string]string),
+				Incremental:    true,
+				Tags:           make(map[string]string),
+				VolumeContext:  make(map[string]string),
+				DeviceSettings: make(map[string]string),
 			},
 			expectedError: nil,
 		},
@@ -1378,9 +1379,10 @@ func TestParseDiskParameters(t *testing.T) {
 			name:        "invalid field in parameters",
 			inputParams: map[string]string{"invalidField": "someValue"},
 			expectedOutput: ManagedDiskParameters{
-				Incremental:   true,
-				Tags:          make(map[string]string),
-				VolumeContext: map[string]string{"invalidField": "someValue"},
+				Incremental:    true,
+				Tags:           make(map[string]string),
+				VolumeContext:  map[string]string{"invalidField": "someValue"},
+				DeviceSettings: make(map[string]string),
 			},
 			expectedError: fmt.Errorf("invalid parameter %s in storage class", "invalidField"),
 		},
@@ -1388,9 +1390,10 @@ func TestParseDiskParameters(t *testing.T) {
 			name:        "invalid value in parameters",
 			inputParams: map[string]string{consts.LogicalSectorSizeField: "invalidValue"},
 			expectedOutput: ManagedDiskParameters{
-				Incremental:   true,
-				Tags:          make(map[string]string),
-				VolumeContext: map[string]string{consts.LogicalSectorSizeField: "invalidValue"},
+				Incremental:    true,
+				Tags:           make(map[string]string),
+				VolumeContext:  map[string]string{consts.LogicalSectorSizeField: "invalidValue"},
+				DeviceSettings: make(map[string]string),
 			},
 			expectedError: fmt.Errorf("parse invalidValue failed with error: strconv.Atoi: parsing \"invalidValue\": invalid syntax"),
 		},
@@ -1474,6 +1477,7 @@ func TestParseDiskParameters(t *testing.T) {
 					consts.IncrementalField:         "false",
 					consts.ZonedField:               "ignored",
 				},
+				DeviceSettings:    make(map[string]string),
 				MaxShares:         1,
 				LogicalSectorSize: 1,
 			},
diff --git a/pkg/optimization/device_perf_helper_test.go b/pkg/optimization/device_perf_helper_test.go
index 3735ccbc9..a52c92c07 100644
--- a/pkg/optimization/device_perf_helper_test.go
+++ b/pkg/optimization/device_perf_helper_test.go
@@ -17,6 +17,7 @@ limitations under the License.
 package optimization
 
 import (
+	"strings"
 	"testing"
 
 	consts "sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
@@ -43,6 +44,11 @@ func TestIsValidPerfProfile(t *testing.T) {
 			profile: "basic",
 			want:    true,
 		},
+		{
+			name:    "advanced profile should return true",
+			profile: "advanced",
+			want:    true,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -67,13 +73,13 @@ func TestGetDiskPerfAttributes(t *testing.T) {
 	}{
 		{
 			name:               "valid attributes should return all values",
-			wantProfile:        "basic",
+			wantProfile:        "advanced",
 			wantAccountType:    "Premium_LRS",
 			wantDiskSizeGibStr: "1024",
 			wantDiskIopsStr:    "100",
 			wantDiskBwMbpsStr:  "500",
 			wantErr:            false,
-			inAttributes:       map[string]string{consts.PerfProfileField: "basic", consts.SkuNameField: "Premium_LRS", consts.RequestedSizeGib: "1024", consts.DiskIOPSReadWriteField: "100", consts.DiskMBPSReadWriteField: "500"},
+			inAttributes:       map[string]string{consts.PerfProfileField: "advanced", consts.SkuNameField: "Premium_LRS", consts.RequestedSizeGib: "1024", consts.DiskIOPSReadWriteField: "100", consts.DiskMBPSReadWriteField: "500", consts.DeviceSettingsKeyPrefix + "queue/read_ahead_kb": "8", consts.DeviceSettingsKeyPrefix + "queue/nomerges": "0"},
 		},
 		{
 			name:               "incorrect profile should return error",
@@ -99,13 +105,16 @@ func TestGetDiskPerfAttributes(t *testing.T) {
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			gotProfile, gotAccountType, gotDiskSizeGibStr, gotDiskIopsStr, gotDiskBwMbpsStr, gotErr := GetDiskPerfAttributes(tt.inAttributes)
+			gotProfile, gotAccountType, gotDiskSizeGibStr, gotDiskIopsStr, gotDiskBwMbpsStr, settings, gotErr := GetDiskPerfAttributes(tt.inAttributes)
 
 			if (gotErr != nil) != tt.wantErr {
 				t.Errorf("GetDiskPerfAttributes() gotErr = %v, want %v", gotErr, tt.wantErr)
 			}
 
 			if !tt.wantErr {
+				if strings.EqualFold(tt.wantProfile, "advanced") && len(settings) == 0 {
+					t.Errorf("GetDiskPerfAttributes() setting is not parsed")
+				}
 				if gotProfile != tt.wantProfile {
 					t.Errorf("GetDiskPerfAttributes() gotProfile = %v, want %v", gotProfile, tt.wantProfile)
 				}
@@ -125,6 +134,7 @@ func TestGetDiskPerfAttributes(t *testing.T) {
 		})
 	}
 }
+
 func TestIsPerfTuningEnabled(t *testing.T) {
 	tests := []struct {
 		name    string
@@ -146,6 +156,11 @@ func TestIsPerfTuningEnabled(t *testing.T) {
 			profile: "blah",
 			want:    false,
 		},
+		{
+			name:    "advanced profile should return true",
+			profile: "advanced",
+			want:    true,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
diff --git a/pkg/optimization/device_perf_linux_test.go b/pkg/optimization/device_perf_linux_test.go
index d6dee6926..5d03ec390 100644
--- a/pkg/optimization/device_perf_linux_test.go
+++ b/pkg/optimization/device_perf_linux_test.go
@@ -20,13 +20,22 @@ limitations under the License.
 package optimization
 
 import (
+	"fmt"
 	"os"
 	"path"
 	"strings"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	consts "sigs.k8s.io/azuredisk-csi-driver/pkg/azureconstants"
 )
 
 func Test_OptimizeDiskPerformance(t *testing.T) {
+	cwd, err := os.Getwd()
+	require.NoError(t, err)
+
 	deviceHelper := NewDeviceHelper()
 	tests := []struct {
 		name                string
@@ -39,6 +48,7 @@ func Test_OptimizeDiskPerformance(t *testing.T) {
 		diskBwMbpsStr       string
 		wantErr             bool
 		blockDeviceRootPath string
+		volumeContext       map[string]string
 		mkdirPath           []string
 	}{
 		{
@@ -51,7 +61,7 @@ func Test_OptimizeDiskPerformance(t *testing.T) {
 			diskIopsStr:         "100",
 			diskBwMbpsStr:       "100",
 			wantErr:             true,
-			blockDeviceRootPath: ".",
+			blockDeviceRootPath: cwd,
 			mkdirPath:           []string{""},
 		},
 		{
@@ -64,7 +74,7 @@ func Test_OptimizeDiskPerformance(t *testing.T) {
 			diskIopsStr:         "100",
 			diskBwMbpsStr:       "100",
 			wantErr:             true,
-			blockDeviceRootPath: ".",
+			blockDeviceRootPath: cwd,
 			mkdirPath:           []string{"queue"},
 		},
 		{
@@ -77,7 +87,7 @@ func Test_OptimizeDiskPerformance(t *testing.T) {
 			diskIopsStr:         "100",
 			diskBwMbpsStr:       "100",
 			wantErr:             true,
-			blockDeviceRootPath: ".",
+			blockDeviceRootPath: cwd,
 			mkdirPath:           []string{"queue/iosched"},
 		},
 		{
@@ -90,7 +100,7 @@ func Test_OptimizeDiskPerformance(t *testing.T) {
 			diskIopsStr:         "100",
 			diskBwMbpsStr:       "100",
 			wantErr:             false,
-			blockDeviceRootPath: ".",
+			blockDeviceRootPath: cwd,
 			mkdirPath:           []string{"queue/iosched", "device"},
 		},
 	}
@@ -108,7 +118,7 @@ func Test_OptimizeDiskPerformance(t *testing.T) {
 				}
 			}
 			if deviceHelper.DiskSupportsPerfOptimization(tt.perfProfile, tt.accountType) {
-				if err := deviceHelper.OptimizeDiskPerformance(tt.nodeInfo, tt.devicePath, tt.perfProfile, tt.accountType, tt.diskSizeGibStr, tt.diskIopsStr, tt.diskBwMbpsStr); (err != nil) != tt.wantErr {
+				if err := deviceHelper.OptimizeDiskPerformance(tt.nodeInfo, tt.devicePath, tt.perfProfile, tt.accountType, tt.diskSizeGibStr, tt.diskIopsStr, tt.diskBwMbpsStr, tt.volumeContext); (err != nil) != tt.wantErr {
 					t.Errorf("DeviceHelper.OptimizeDiskPerformance() error = %v, wantErr %v", err, tt.wantErr)
 				}
 			}
@@ -205,6 +215,141 @@ func Test_getOptimalDeviceSettings(t *testing.T) {
 	}
 }
 
+func Test_getDeviceSettingsForBasicProfile(t *testing.T) {
+	accountType := "Premium_LRS"
+	tier := "Premium"
+	sizeP20 := "P20"
+	sizeP30 := "P30"
+	diskSkus := make(map[string]map[string]DiskSkuInfo)
+	diskSkus[strings.ToLower(accountType)] = map[string]DiskSkuInfo{}
+	diskSkus[strings.ToLower(accountType)][strings.ToLower(sizeP20)] = DiskSkuInfo{StorageAccountType: accountType, StorageTier: tier, DiskSize: sizeP20, MaxIops: 100, MaxBurstIops: 100, MaxBwMbps: 500, MaxBurstBwMbps: 500, MaxSizeGiB: 1024}
+	diskSkus[strings.ToLower(accountType)][strings.ToLower(sizeP30)] = DiskSkuInfo{StorageAccountType: accountType, StorageTier: tier, DiskSize: sizeP30, MaxIops: 200, MaxBurstIops: 200, MaxBwMbps: 1000, MaxBurstBwMbps: 1000, MaxSizeGiB: 4096}
+	skuName := "Standard_DS14"
+	nodeInfo := &NodeInfo{SkuName: skuName, MaxBurstIops: 51200, MaxIops: 51200, MaxBwMbps: 512, MaxBurstBwMbps: 512}
+
+	tests := []struct {
+		name             string
+		perfProfile      string
+		accountType      string
+		DiskSizeGibStr   string
+		diskIopsStr      string
+		diskBwMbpsStr    string
+		wantQueueDepth   string
+		wantNrRequests   string
+		wantScheduler    string
+		wantMaxSectorsKb string
+		wantReadAheadKb  string
+		wantErr          bool
+		node             *NodeInfo
+	}{
+		{
+			name:           "Should return valid disk perf settings",
+			perfProfile:    "basic",
+			accountType:    "Premium_LRS",
+			DiskSizeGibStr: "512",
+			diskIopsStr:    "100",
+			diskBwMbpsStr:  "100",
+			wantScheduler:  "mq-deadline",
+			wantErr:        false,
+			node:           nodeInfo,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			deviceSettings, err := getDeviceSettingsForBasicProfile(tt.node, "", tt.perfProfile, tt.accountType, tt.DiskSizeGibStr, tt.diskIopsStr, tt.diskBwMbpsStr)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("getDeviceSettingsForBasicProfile() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			} else if !tt.wantErr {
+				if len(deviceSettings) == 0 {
+					t.Errorf("getDeviceSettingsForBasicProfile() failed for get deviceSettings")
+				}
+			}
+		})
+	}
+}
+
+func Test_getDeviceSettingsForAdvancedProfile(t *testing.T) {
+	tests := []struct {
+		name     string
+		wantErr  bool
+		node     *NodeInfo
+		settings map[string]string
+	}{
+		{
+			name:    "Should return valid disk perf settings if settings are passed",
+			wantErr: false,
+			settings: map[string]string{
+				"device/nr_request": "8",
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			deviceSettings, err := getDeviceSettingsForAdvancedProfile("/sys/block/sda", tt.settings)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("getDeviceSettingsForAdvancedProfile() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			} else if !tt.wantErr {
+				if len(deviceSettings) == 0 {
+					t.Errorf("getDeviceSettingsForAdvancedProfile() failed for get deviceSettings")
+				}
+			}
+		})
+	}
+}
+
+func Test_applyDeviceSettings(t *testing.T) {
+	tests := []struct {
+		name          string
+		wantErr       bool
+		settings      map[string]string
+		expectedError error
+	}{
+		{
+			name:          "Should fail if nil settings provided",
+			wantErr:       true,
+			settings:      nil,
+			expectedError: fmt.Errorf("AreDeviceSettingsValid: No deviceSettings passed"),
+		},
+		{
+			name:          "Should fail if empty settings provided",
+			wantErr:       true,
+			settings:      map[string]string{},
+			expectedError: fmt.Errorf("AreDeviceSettingsValid: No deviceSettings passed"),
+		},
+		{
+			name:    "Should fail if setting with non absolute path provided",
+			wantErr: true,
+			settings: map[string]string{
+				consts.DummyBlockDevicePathLinux + "/../device/nr_request": "8",
+			},
+			expectedError: fmt.Errorf("AreDeviceSettingsValid: Setting %s is not a valid file path under %s",
+				consts.DummyBlockDevicePathLinux+"/../device/nr_request",
+				consts.DummyBlockDevicePathLinux),
+		},
+		{
+			name:    "Should fail if setting with incorrect prefix provided",
+			wantErr: true,
+			settings: map[string]string{
+				"/sys/block/sdaa/device/nr_request": "8",
+			},
+			expectedError: fmt.Errorf("AreDeviceSettingsValid: Setting %s is not a valid file path under %s",
+				"/sys/block/sdaa/device/nr_request",
+				consts.DummyBlockDevicePathLinux),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			err := applyDeviceSettings(consts.DummyBlockDevicePathLinux, tt.settings)
+			if tt.wantErr {
+				assert.Equal(t, tt.expectedError, err)
+				return
+			}
+		})
+	}
+}
+
 func Test_getMatchingDiskSku(t *testing.T) {
 	accountType := "Premium_LRS"
 	tier := "Premium"
diff --git a/pkg/optimization/device_perf_test.go b/pkg/optimization/device_perf_test.go
index ce4effbd6..0bfdf3cd7 100644
--- a/pkg/optimization/device_perf_test.go
+++ b/pkg/optimization/device_perf_test.go
@@ -59,6 +59,12 @@ func TestSafeDeviceHelper_DeviceSupportsPerfOptimization(t *testing.T) {
 			diskAccountType: "Premium_lrs",
 			want:            util.IsLinuxOS(),
 		},
+		{
+			name:            "valid profile and account should return true",
+			diskPerfProfile: "advanced",
+			diskAccountType: "Premium_lrs",
+			want:            util.IsLinuxOS(),
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -131,7 +137,7 @@ func TestDeviceHelper_OptimizeDiskPerformance(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			if deviceHelper.DiskSupportsPerfOptimization(tt.perfProfile, tt.accountType) {
-				if err := deviceHelper.OptimizeDiskPerformance(tt.nodeInfo, tt.devicePath, tt.perfProfile, tt.accountType, tt.diskSizeGibStr, tt.diskIopsStr, tt.diskBwMbpsStr); (err != nil) != tt.wantErr {
+				if err := deviceHelper.OptimizeDiskPerformance(tt.nodeInfo, tt.devicePath, tt.perfProfile, tt.accountType, tt.diskSizeGibStr, tt.diskIopsStr, tt.diskBwMbpsStr, nil); (err != nil) != tt.wantErr {
 					t.Errorf("DeviceHelper.OptimizeDiskPerformance() error = %v, wantErr %v", err, tt.wantErr)
 				}
 			}
diff --git a/test/e2e/dynamic_provisioning_test.go b/test/e2e/dynamic_provisioning_test.go
index a5331b7b0..d036f53ee 100644
--- a/test/e2e/dynamic_provisioning_test.go
+++ b/test/e2e/dynamic_provisioning_test.go
@@ -1146,6 +1146,50 @@ func (t *dynamicProvisioningTestSuite) defineTests(isMultiZone bool) {
 		}
 		test.Run(cs, ns)
 	})
+
+	ginkgo.It("should succeed with advanced perfProfile [disk.csi.azure.com] [Windows]", func() {
+		skipIfUsingInTreeVolumePlugin()
+		skipIfOnAzureStackCloud()
+		skipIfTestingInWindowsCluster()
+		pods := []testsuites.PodDetails{
+			{
+				Cmd: convertToPowershellorCmdCommandIfNecessary("echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data"),
+				Volumes: t.normalizeVolumes([]testsuites.VolumeDetails{
+					{
+						ClaimSize: "10Gi",
+						MountOptions: []string{
+							"barrier=1",
+							"acl",
+						},
+						VolumeMount: testsuites.VolumeMountDetails{
+							NameGenerate:      "test-volume-",
+							MountPathGenerate: "/mnt/test-",
+						},
+						VolumeAccessMode: v1.ReadWriteOnce,
+					},
+				}, isMultiZone),
+				IsWindows:    isWindowsCluster,
+				WinServerVer: winServerVer,
+			},
+		}
+		test := testsuites.DynamicallyProvisionedCmdVolumeTest{
+			CSIDriver: testDriver,
+			Pods:      pods,
+			StorageClassParameters: map[string]string{
+				"skuname":                             "StandardSSD_LRS",
+				"perfProfile":                         "advanced",
+				"device-setting/queue/max_sectors_kb": "211",
+				"device-setting/queue/scheduler":      "none",
+				"device-setting/device/queue_depth":   "17",
+				"device-setting/queue/nr_requests":    "44",
+				"device-setting/queue/read_ahead_kb":  "256",
+				"device-setting/queue/wbt_lat_usec":   "0",
+				"device-setting/queue/rotational":     "0",
+			},
+		}
+
+		test.Run(cs, ns)
+	})
 }
 
 // Normalize volumes by adding allowed topology values and WaitForFirstConsumer binding mode if we are testing in a multi-az cluster